Hitachi

JP1 Version 12 JP1/IT Desktop Management 2 - Asset Console アクセス定義ファイル作成ガイド


$DLLLOAD(DLLロード関数)

ユーザ関数を実装したDLLをロードし、オブジェクトを取得します。

ロードに成功すると、取得したDLLオブジェクトを返します。ロードに失敗した場合、0バイトの文字列を返します。

〈このページの構成〉

形式

DLLオブジェクト=$DLLLOAD(DLL名)

指定する値

使用するDLLのインターフェース

呼び出されるDLLに、次の3つの実行制御関数をエクスポートしておく必要があります。

各実行制御関数の形式を次に示します。

void* aim_init()
void aim_free(void* dllobj)
int aim_getmessage(void* dllobj, char** msg)

DLLのロード成功時は、インスタンス生成のためにaim_init関数を呼び出します。aim_init関数のリターンには、エラーがありません。エラー発生時に、詳細なエラー情報をログファイルに出力するには、エラーメッセージのアドレスなどをaim_init関数のリターン情報としてください。また、エラーメッセージをAsset Consoleのログファイルに出力するには、aim_init関数のあとに呼び出されるaim_getmessage関数でメッセージを設定してください。

スクリプト側では、エラーを組み込み関数$GETSTATUSで検出したら、組み込み関数$DLLFREEを実行し、DLLを解放してください。$DLLFREEの実行によってaim_free関数が呼び出されるので、aim_init関数のリターン情報の情報域を開放してください。

なお、aim_init関数が正常終了した場合には、必ずaim_getmessage関数は0をリターンしてください。これで組み込み関数$DLLEXEC2が実行可能な状態となります。

終了状態

処理の終了状態とその内容を次に示します。

終了状態

内容

NORMAL

正常終了

NODATA

ERROR

次のどれかを示す

  • 指定したDLLが存在しない

  • DLLのロードに失敗した

  • DLL内に必要な関数のエントリが見つからない

スクリプト中断

次のどれかを示す

  • 指定したDLLが存在しない

  • DLLのロードに失敗した

  • 引数の誤り、またはそのほかのエラー

(凡例)

−:該当しない

注意事項

組み込み関数$DLLLOADでロードするDLLは、あらかじめ用意しておく必要があります。コンパイル時には、Asset Consoleが提供しているヘッダーファイルをソースファイルと一緒にコンパイル環境に格納して、コンパイルしてください。また、コンパイルする際は、オプションに「/MT」を指定してください。

ヘッダーファイルの格納先を次に示します。

Asset Consoleのインストール先フォルダ\sdk\include

記述例

$DLLEXEC2(DLL実行関数)の記述例を参照してください。

実行制御関数の作成

Asset ConsoleのスクリプトからDLLのユーザ関数を呼び出すためには、次の3つの実行制御関数が必要です。

■aim_init

機能

インスタンスを作成し、戻り値にそのアドレスを設定します。これによって、それ以降ほかの関数では、aim_init関数で作成したアドレスを取得できます。インスタンス内に値を保持することで、スレッド間の競合を避けられます。

形式
void* aim_init()
戻り値
  • 関数が成功した場合、このDLLで使用するハンドルのアドレスを返します。アドレスはNULLでもかまいません。リターン直後、aim_getmessage関数が呼ばれるので、必ず0をリターンしてください。

  • 継続可能なエラーや、エラーの内容をAsset Consoleのログファイルに出力する場合、エラー情報を設定したハンドルのアドレスを返して、aim_getmessage関数でメッセージを取得できるようにします。また、同時にスクリプトの終了状態を決定するリターンコードを返すようにします。リターンコードについては、aim_getmessage関数の戻り値を参照してください。

■aim_free

機能

aim_init関数で作成したインスタンスを解放します。

形式
void aim_free(void* dllobj)
引数
  • dllobj(入力情報)

    aim_init関数で作成したインスタンス

■aim_getmessage

機能

作成するDLL内のメッセージを、Asset Consoleのログに出力したり、スクリプトで容易に取得したりできます。aim_getmessage関数は、次に示すタイミングで呼び出されます。

  • aim_init関数の実行後

    msgの内容をAsset Consoleのログに出力します。

  • 作成した関数の実行後

    関数の戻り値が負数(スクリプト中断エラー発生時)の場合に実行し、必要に応じてmsgにアドレスを設定します。メッセージを設定した場合は、msgの内容がAsset Consoleのログに出力されます。

  • 組み込み関数$DLLMSG実行時

    組み込み関数$DLLMSGで実行され、メッセージを変数で取得します。

形式
int aim_getmessage(void* dllobj, char** msg)
引数
  • dllobj(入力情報)

    aim_init関数で作成したインスタンス

  • msg(出力情報)

    メッセージが格納されたアドレス

戻り値

戻り値と内容、および戻り値に応じて実行される処理を次に示します。

戻り値

内容

実行できる処理

0

正常終了

スクリプトの状態をNORMALに変更

1

Warning

スクリプトの状態をNODATAに変更

正数

Error

スクリプトの状態をERRORに変更

負数

強制終了

スクリプトを強制終了

コーディング例

DLLのソースファイルのコーディング例を示したあと、アクセス定義ファイルからの呼び出しと関連づけについて説明します。

  • DLLのソースファイル(C++)

#include <stdio.h>
#include <windows.h>
 
#include "jamScriptAPI.h"
extern "C" __declspec(dllexport) void*  aim_init();
extern "C" __declspec(dllexport) void   aim_free(void*);
extern "C" __declspec(dllexport) int    aim_getmessage(void*, char**);
extern "C" __declspec(dllexport) int    DllFunc1(int, void**);
extern "C" __declspec(dllexport) int    DllFunc2(int, void**);
 
typedef struct aimsample{
    int         status;
    int         datalen;
    char**      data;
    char        message[256];
}AIMSAMPLE;
 
BOOL APIENTRY DllMain( HANDLE hModule,
                        DWORD  ul_reason_for_call,
                        LPVOID lpReserved
                     )
{
    return TRUE;
}
void* aim_init()
{
    AIMSAMPLE* dllobj = NULL;
    dllobj = (AIMSAMPLE*)LocalAlloc(LMEM_FIXED, sizeof(AIMSAMPLE));
    if(!dllobj) {
        /* エラー処理 */
        return NULL;
    }
    dllobj->status = 0;
    dllobj->datalen = 0;
    dllobj->data = NULL;
    *(dllobj->message) = '\0';
    return dllobj;
}
void aim_free(void* dllobj)
{
    int i;
    if(dllobj){
        if(dllobj->data){
            for(i=0;i<dllobj->datalen;i++){
                if(*(dllobj->data+i)){
                    LocalFree(*(dllobj->data+i));
                    *(dllobj->data+i) = NULL;
                }
            }
            LocalFree(dllobj->data);
            dllobj->data = NULL;
        }
        LocalFree(dllobj);
    }
}
int aim_getmessage(void* dllobj, char** message)
{
    if(dllobj){
        *message = ((AIMSAMPLE*)dllobj)->message;
    }
    return 0;
}
int DllFunc1(int argc, void** argv)
{
    AIMSAMPLE* dllobj = NULL;
    int i,status,length;
    char* data;
    if(argc != 1){ 
       /* エラー処理 */
        return -1;
    }
    /*aim_initで返却したエリアを取得*/
    dllobj = (AIMSAMPLE*)$GETINITAREA(argv);
    if(!dllobj){
        /* エラー処理 */
        strcpy(dllobj->message, "引数の指定に誤りがあります。");
        return -1;
    }
    if(dllobj->status != 0){
        strcpy(dllobj->message, "呼び出し順序に誤りがあります。");
        return -1;
    }
    length = $GETARRAYLENGTH(argv, argv[0]);
    status = $GETSTATUS(argv);
    if(status != JAM_SCRIPTAPI_NORMAL){
        /* エラー処理 */
        strcpy(dllobj->message, "$GETARRAYLENGTH関数でエラーを検知しました。");
        return -1;
    }
    dllobj->datalen = length;
    dllobj->data = (char**)LocalAlloc(LMEM_FIXED, sizeof(char*)*length);
    if(!dllobj->data){
        /* エラー処理 */
        strcpy(dllobj->message, "メモリ確保に失敗しました。");
        return -1;
    }
    ZeroMemory(dllobj->data, sizeof(char*)*length);
    for(i=0;i<length;i++){
        data = (char*)$GETARRAY(argv, argv[0], i+1);
        status = $GETSTATUS(argv);
        if(status != JAM_SCRIPTAPI_NORMAL){
            /* エラー処理 */
            strcpy(dllobj->message, "$GETARRAY関数でエラーを検知しました。");
            return -1;
        }
        *(dllobj->data+length-(i+1)) = (char*)LocalAlloc(LMEM_FIXED, strlen(data)+1);
        if(!*(dllobj->data+length-(i+1))){
            /* エラー処理 */
            strcpy(dllobj->message, "メモリ確保に失敗しました。");
            return -1;
        }
        strcpy(*(dllobj->data+length-(i+1)), data);
    }
    /* 固有の処理 */
    dllobj->status = 1;
    *(dllobj->message) = '\0';
    return 0;
}
int DllFunc2(int argc, void** argv)
{
    AIMSAMPLE* dllobj = NULL;
    int i;
    if(argc != 1){
        /* エラー処理 */
        return -1;
    }
    /*aim_initで返却したエリアを取得*/
    dllobj = (AIMSAMPLE*)$GETINITAREA(argv);
    if(!dllobj){
        /* エラー処理 */
        return -1;
    }
    if(dllobj->status != 1){
        strcpy(dllobj->message, "呼び出し順序に誤りがあります。");
        return -1;
    }
    if(dllobj->data){
        for(i=0;i<dllobj->datalen;i++){
            if(*(dllobj->data+i)){
                $SETARRAY(argv, argv[0], *(dllobj->data+i));
            }
        }
    }
    dllobj->status = 2;
    *(dllobj->message) = '\0';
    return 0;
}
  • アクセス定義ファイルからの呼び出しと関連づけ

    この例では、「DllFunc1」で取得した配列データの逆順を「DllFunc2」で出力します。また、「DllFunc1」、「DllFunc2」の順序で実行されない場合には、スクリプトを中断します。

#AssetInformationManager HTML 0005
 
[VAR]
  DLLOBJ
  DATA
  STATUS[ARRAY]
  ARY1
  ARY2
[SET_VALUE]
  DLLOBJ = $DLLLOAD('jamsample.dll')
  STATUS = $GETSTATUS()
[IF]
  STATUS != NORMAL
[THEN]
  [SET_VALUE]
      #エラー処理
      $EXIT(1)
[IF_END]
[SET_VALUE]
  $SETARRAY(ARY1, 1)
  $SETARRAY(ARY1, 2)
  $SETARRAY(ARY1, 3)
  $DLLEXEC2(DLLOBJ,'DllFunc1',ARY1)
  $DLLEXEC2(DLLOBJ,'DllFunc2',ARY2)
  DATA = $GETARRAY(ARY2,1)
  $ECHO(DATA)
  DATA = $GETARRAY(ARY2,2)
  $ECHO(DATA)
  DATA = $GETARRAY(ARY2,3)
  $ECHO(DATA)
  $DLLFREE(DLLOBJ)
出力結果

3

2

1