次の手順で、fact ADSrx アプリケーションをビルドし実行します
- お使いのIJCADのバージョンに合わせたVisual Studio を起動します。
IJCAD 統合開発環境 2020以降 Visual Studio 2017 2014 から 2019 まで Visual Studio 2010 - ファイルメニュー ► 開く ► プロジェクト/ソリューション を選択します。
- ソリューションファイル C:\GRXSDK\Samples\fact_dg\fact.sln を開きます。
- 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; |
|||
リンカー 入力 | モジュール定義ファイル | C:\GRXSDK\Inc\arx\rxexport.def | |||
リンカー デバッグ | デバッグ情報の生成 | はい(/DEBUG) | |||
リンカー 詳細設定 | 対象コンピューター | MachineX86 | MachineX64 |
ADS アプリケーションのビルド
次の手順で、ADS アプリケーションを GRX アプリケーションとしてビルドできます。
- ビルドを行うソリューション プラットフォームとソリューション構成を選択します。
- ビルドメニュー ► 開く ► ソリューションのビルド を選択します。
- ビルドメニュー ► 開く ► バッチビルド から必要な構成をまとめてビルドできます。
ADS アプリケーションの実行
次の手順で, ADS アプリケーションを実行できます.
- IJCAD を起動します。
- APPLOADコマンドを実行します。
- FACT.GRX ファイルをロードします。
- コマンドプロンプトに(fact 5)と入力すると、5の階乗を求めて120を返します。
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.