フォローする

ADS - fact ADSRxアプリケーションのビルドと実行

更新 : 2017-02-02 06:21:52 UTC

次の手順で、fact ADSrx アプリケーションをビルドし実行します

  1. Visual Studio 2010 を起動します。
  2. ファイルメニュー ► 開く ► プロジェクト/ソリューション を選択します。
  3. ソリューションファイル C:\GRXSDK\Samples\fact_dg\fact.sln を開きます。
  4. x64構成がなければ構成マネージャで追加してください。詳しい手順はこちらを参照してください。
ページ 項目 Win32 Release Win32 Debug x64 Release x64 Debug
プロジェクトの設定
全般 構成の種類 ダイナミックライブラリ(.dll)
全般 文字セット Unicode文字セットを使用する
全般 出力ディレクトリ $(SolutionDir)$(Platform)\$(Configuration)\
全般 中間ディレクトリ $(Platform)\$(Configuration)\
全般 ターゲットの拡張子 .grx
C/C++ 全般 追加のインクルード ディレクトリ C:\GRXSDK\Inc;C:\GRXSDK\Inc\arx
C/C++ プリプロセッサ プリプロセッサの定義 _TOOLKIT_IN_DLL_;%(PreprocessorDefinitions)
C/C++ コード生成 ランタイムライブラリ マルチスレッド DLL(/MD)
C/C++ 詳細設定 指定の警告を無効にする 4819
リンカー 全般 追加のライブラリ ディレクトリ C:\GRXSDK\lib-x86 C:\GRXSDK\lib-x64
リンカー 入力 追加の依存ファイル

grxport.lib;gcad.lib;gcap.lib;gcdb.lib;
gced.lib;gcgs.lib;gcui.lib;gcut.lib;
Td_Root.lib;Td_DbRoot.lib;Td_Db.lib;
Td_Ge.lib;Td_Gi.lib;Td_Gs.lib

リンカー 入力 モジュール定義ファイル C:\GRXSDK\Inc\arx\rxexport.def
リンカー デバッグ デバッグ情報の生成 はい(/DEBUG)
リンカー 詳細設定 対象コンピューター MachineX86 MachineX64

ADS アプリケーションのビルド

次の手順で、ADS アプリケーションを GRX アプリケーションとしてビルドできます。

  1. ビルドを行うソリューション プラットフォームとソリューション構成を選択します。
  2. ビルドメニュー ► 開く ► ソリューションのビルド を選択します。
  3. ビルドメニュー ► 開く ► バッチビルド から必要な構成をまとめてビルドできます。

ADS アプリケーションの実行

次の手順で, ADS アプリケーションを実行できます.

  1. IJCAD を起動します。
  2. APPLOADコマンドを実行します。
  3. FACT.GRX ファイルをロードします。
  4. コマンドプロンプトに (fact 5) と入力すると、5の階乗を求めて 240 を返します。

fact.cpp ファイル

もともと main() 関数や WIN_Main() 関数が ADSアプリケーションの入り口でした。

ADSrx になり、main() 関数が、acrxEntryPoint() 関数に置き換わりました。

GRX は、ADSRx アプリケーションのソースコードを最小限の修正でビルドできます。

#include  "adslib.h"
#include  "rxregsvc.h"
#include  "tchar.h"


/* Utility definition to get an  array's  element  count  (at  compile
   time).   For  example:  

       int  arr[] = {1,2,3,4,5};
       ... 
       printf("%d", ELEMENTS(arr));

   would print a five.  ELEMENTS("abc") can also be used to  tell  how
   many  bytes are in a string constant INCLUDING THE TRAILING NULL. */

#define ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))


/* All the functions that we'll define will be listed in a single table,
   together with the internal function that we call to handle each.  The
   functions all take a single argument (the resbuf that has the
   arguments) and return an integer (RTNORM or RTERROR for good or bad
   status).  */


/* First, define the structure of the table: a string giving the AutoCAD name
   of the function, and a pointer to a function returning type int. */
struct func_entry { TCHAR *func_name; int (*func) (struct resbuf *); };

/* Here we declare the functions that handle the calls; at the moment there are
   two of them. */
static int fact       (struct resbuf *rb);
static int squareroot (struct resbuf *rb);

/* Here we define the array of function names and handlers. */
static struct func_entry func_table[] = { {_T(/*MSG0*/"fact"), fact},
                                          {_T(/*MSG0*/"sqr"), squareroot},
                                        };
/* To add more functions to this table, just put them in the list, after
   declaring the function names.  Note that in standard C it's all right to
   have a superfluous comma after the last item.  */


/* The code from here to the end of dofun() is UNCHANGED when you add or delete
   functions. */


/*  Declarations of other local functions  */
void            main       (int, char**);
static int      dofun      (void);
static int      funcload   (void);
static int		funcunload (void);
static ads_real rfact      (int x);
static ads_real rsqr       (ads_real x);

/*-----------------------------------------------------------------------*/
/* ACRXENTRYPOINT -- This function replaces main() for an ARX program. */
#if 1

extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* appId)
{
    switch(msg) {
    case AcRx::kInitAppMsg:
        acrxDynamicLinker->unlockApplication(appId);
		acrxDynamicLinker->registerAppMDIAware(appId);
        break;
    case AcRx::kInvkSubrMsg:
        dofun();
        break;
    case AcRx::kLoadDwgMsg:
        funcload();
    }
    return AcRx::kRetOK;
}

#else
/*-----------------------------------------------------------------------*/
/* main() -- true ADS application has main().	*/

int main(int argc, char** argv)
{
   int status;
   char errorstr[80];
   short scode = RSRSLT;             

   ads_init(argc, argv);  // Start communications with lisp

   for ( ;; ) 
   {                      // Communication loop
       if ((status = ads_link(scode)) < 0) 
	   {
           ads_printf(errorstr);
           ads_exit(0);
       }
       scode = RSRSLT;               

       switch (status) 
	   {
       case RQXLOAD:
           scode = ( funcload() == RTNORM ? RSRSLT : RSERR );
           break;
       case RQXUNLD:
       case RQQUIT:
           scode = ( funcunload() == RTNORM ? RSRSLT : RSERR );
           break;
       case RQSUBR:                  
           scode = ( dofun() == RTNORM ? RSRSLT : RSERR );
           break;
       default:
           break;
       }
   }
   return 1;
}

#endif

/*-----------------------------------------------------------------------*/
/* FUNCLOAD  --  Define this application's external functions.  Return
                 RTERROR on error, else RTNORM.                   */

static int funcload()
{
    int i;

    for (i = 0; i < ELEMENTS(func_table); i++) {
        if (!ads_defun(func_table[i].func_name, (short)i))
            return RTERROR;
    }
    return RTNORM;
}

/*-----------------------------------------------------------------------*/
/* DOFUN -- Execute external function (called upon an RQSUBR request).  
            Return value from the function executed, RTNORM or RTERROR. */

static int dofun()
{
    struct resbuf *rb;
    int val;

    /* Get the function code and check that it's within range.
       (It can't fail to be, but paranoia doesn't hurt.) */
    if ((val = ads_getfuncode()) < 0 || val >= ELEMENTS(func_table)) {
        ads_fail(_T(/*MSG2*/"Received nonexistent function code."));
        return RTERROR;
    }

    /* Fetch the arguments, if any. */
    rb = ads_getargs();

    /* Call the handler and return its success-failure status. */
    val = (*func_table[val].func)(rb);

    return val;
}

/*-----------------------------------------------------------------------*/
/* FUNCUNLOAD  --  Undefine this application's external functions.
	Return RTERROR on error, else RTNORM.
	NOTE: ADSrx application do not have to use ads_undef() when unload document notification is received.
	*/

static int funcunload()
{
    int i;

    for (i = 0; i < ELEMENTS(func_table); i++) {
        if (!ads_undef(func_table[i].func_name, (short)i))
            return RTERROR;
    }
    return RTNORM;
}

/* The code from the beginning of main() to here is UNCHANGED when you add or
   delete functions.  */

/*-----------------------------------------------------------------------*/
/* FACT -- First set up the argument, then call the factorial function */
static int
fact(struct resbuf *rb)
{
    int x;

    if (rb == NULL)
        return RTERROR;

    if (rb->restype == RTSHORT) {
        x = rb->resval.rint;          /* Save in local variable */
    } else {
        ads_fail(_T(/*MSG3*/"Argument should be an integer."));
        return RTERROR;
    }

    if (x < 0) {                      /* Check argument range */
        ads_fail(_T(/*MSG4*/"Argument should be positive."));
        return RTERROR;
    } else if (x > 170) {             /* Avoid floating-point overflow */
        ads_fail(_T(/*MSG5*/"Argument should be 170 or less."));
        return RTERROR;
    }

    ads_retreal(rfact(x));            /* Call the function itself, and
                                         return the value to AutoLISP */
    return RTNORM;
}

/*-----------------------------------------------------------------------*/
/* This is the implementation of the actual external factorial function */

static ads_real rfact(int n)
{
    ads_real ans = 1.0;

    while (n)
        ans *= n--;

    return ans;
}

/*-----------------------------------------------------------------------*/
/* SQUAREROOT -- First set up the argument, then call the root function */
static int
squareroot(struct resbuf *rb)
{
    ads_real x;

    if (rb == NULL)
        return RTERROR;               /* A proper error msg would be better */

    if (rb->restype == RTSHORT) {     /* Save in local variable */
        x = (ads_real) rb->resval.rint;
    } else if (rb->restype == RTREAL) {
        x = rb->resval.rreal;         /* Can accept either real
                                         or integer */
    } else {
        ads_fail(_T(/*MSG6*/"Argument should be a real or integer value."));
        return RTERROR;
    }

    if (x < 0) {                      /* Check argument range */
        ads_fail(_T(/*MSG7*/"Argument should be positive."));
        return RTERROR;
    }

    ads_retreal(rsqr(x));             /* Call the function itself, and
                                         return the value to AutoLISP */

    return RTNORM;
}

/*-----------------------------------------------------------------------*/
/* This is the implementation of the actual external function */

static ads_real rsqr(ads_real x)       /* Square root by Newton's method */
{
    int n = 50;
    ads_real y, c, cl;

    if (x == 0.0) {
        return 0.0;
    }

    y = (x * 2 + .1) / (x + 1.0);
    c = (y - x / y) / 2;
    cl= 0.0;

    while ((c != cl) && (n-- > 0)) {
        y -= c;
        cl = c;
        c  = (y - x / y) / 2;
    }
    return y;
}

// END CODE APPEARING IN SDK DOCUMENT.

 

この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています
他にご質問がございましたら、リクエストを送信してください

コメント