$DLLLOAD (load DLL)
$DLLLOAD loads a DLL in which user functions are included, and acquires an object.
When loading is successful, this function returns the acquired DLL object. When loading fails, the function returns a character string of 0 bytes.
- Organization of this page
Syntax
DLL-object=$DLLLOAD(DLL-name)
Values
-
DLL-object
Specifies the name of the variable in which the DLL object is to be set.
-
DLL-name
Specifies the name of DLL to be loaded, as either a constant or a variable. A constant must be enclosed in single quotation marks ('').
Express the DLL name as a path relative to the base path specified in the -bp option of the jamscript command. If the -bp option was omitted, Asset-Console-installation-folder\scriptwork is assumed to be the reference folder.
DLL interface to be used
The following three execution control functions must have been exported previously to the DLL to be called:
-
aim_init function for initializing instances
-
aim_getmessage function for sending error message responses
-
aim_free function for freeing instances
The following shows the format of each execution control function:
void* aim_init() void aim_free(void* dllobj) int aim_getmessage(void* dllobj, char** msg)
When loading of DLL is successful, this function calls the aim_init function to create an instance. The aim_init function returns no error. In the event of an error, to output detailed error information to a log file, use information such as the error message address as the return value of the aim_init function. To output an error message to Asset Console's log file, set the message by using the aim_getmessage function that is called after the aim_init function.
In the script, when an error is detected by the $GETSTATUS embedded function, execute the $DLLFREE embedded function and free the DLL. Because the aim_free function is called when $DLLFREE is executed, free the area for the return value of the aim_init function.
If the aim_init function has terminated normally, make sure that the aim_getmessage function returns 0. This makes the $DLLEXEC2 function executable.
Status
The following table lists and describes the possible statuses:
Status |
Description |
---|---|
NORMAL |
Normal end |
NODATA |
— |
ERROR |
Indicates one of the following:
|
Script execution interrupted |
Indicates one of the following:
|
Note
The user must have provided previously the DLL that is to be loaded by the $DLLLOAD embedded function. Store the header files provided by Asset Console together with the source files in the compilation environment, and then compile them. During the compilation, specify the /MT option.
The header files are stored at the following location:
Asset-Console-installation-folder\sdk\include
Example
See the coding example in $DLLEXEC2 (execute DLL).
Creation of execution control functions
To call a DLL user function from the Asset Console script, the following three execution control functions are required:
-
aim_init
-
aim_free
-
aim_getmessage
■ aim_init
- Function
-
aim_init creates an instance and sets its address in the return value. This enables other functions thereafter to acquire the address created by the aim_init function. By holding values in instances, you can avoid possible conflict between threads.
- Syntax
-
void* aim_init()
- Return value
-
-
If the processing is successful, the function returns the address of the handle used by this DLL. The address may be NULL. Make sure that a value of 0 is returned, because the aim_getmessage function is called immediately after control is returned.
-
To output a resumable error and details about the error to Asset Console's log file, return the address of the handle with the error information set so that the message can be acquired by the aim_getmessage function. At the same time, return the code that determines the termination status of the script. For details about the return code, see Return value of aim_getmessage function.
-
■ aim_free
- Function
-
aim_free frees the instance created by the aim_init function.
- Syntax
-
void aim_free(void* dllobj)
- Arguments
-
-
dllobj(input-information)
Specifies the instance created by the aim_init function.
-
■ aim_getmessage
- Function
-
aim_getmessage enables you to output the messages in the created DLL to Asset Console's log file, and easily acquire them by using a script. The aim_getmessage function is called at the following times:
-
After execution of the aim_init function
The aim_getmessage function outputs the contents of msg to Asset Console's log file.
-
After execution of the created function
If a function returns a negative value (in the event of a script execution interrupted error), the aim_getmessage function is executed and sets the address in msg as required. When a message is set, the contents of msg are output to Asset Console's log file.
-
During execution of the $DLLMSG embedded function
Executed by the $DLLMSG function, the aim_getmessage function acquires the message using variables.
-
- Syntax
-
int aim_getmessage(void* dllobj, char** msg)
- Arguments
-
-
dllobj(input-information)
Specifies the instance created by the aim_init function.
-
msg(output-information)
Specifies the address where the message is stored.
-
- Return value
-
The following table lists and describes the return value and the processing that is executed:
Return value
Description
Executable processing
0
Normal end
Changes the script status to NORMAL.
1
Warning
Changes the script status to NODATA.
Positive value
Error
Changes the script status to ERROR.
Negative value
Forced termination
Forcibly terminates the script.
- Coding example
-
This example presents coding of a DLL source file and its association with a call from the access definition file.
-
Source file of 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) { /* error handling processing */ 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){ /* error handling processing */ return -1; } /* acquire the area returned by aim_init*/ dllobj = (AIMSAMPLE*)$GETINITAREA(argv); if(!dllobj){ /* error handling processing */ strcpy(dllobj->message, "Specified argument is invalid."); return -1; } if(dllobj->status != 0){ strcpy(dllobj->message, "Call sequence is invalid."); return -1; } length = $GETARRAYLENGTH(argv, argv[0]); status = $GETSTATUS(argv); if(status != JAM_SCRIPTAPI_NORMAL){ /* error handling processing */ strcpy(dllobj->message, "Error was detected by $GETARRAYLENGTH function."); return -1; } dllobj->datalen = length; dllobj->data = (char**)LocalAlloc(LMEM_FIXED, sizeof(char*)*length); if(!dllobj->data){ /* error handling processing */ strcpy(dllobj->message, "Memory allocation failed."); 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){ /* error handling processing */ strcpy(dllobj->message, "Error was detected by $GETARRAY function."); return -1; } *(dllobj->data+length-(i+1)) = (char*)LocalAlloc(LMEM_FIXED, strlen(data)+1); if(!*(dllobj->data+length-(i+1))){ /* error handling processing */ strcpy(dllobj->message, "Memory allocation failed."); return -1; } strcpy(*(dllobj->data+length-(i+1)), data); } /* specific processing */ dllobj->status = 1; *(dllobj->message) = '\0'; return 0; } int DllFunc2(int argc, void** argv) { AIMSAMPLE* dllobj = NULL; int i; if(argc != 1){ /* error handling processing */ return -1; } /* acquire the area returned by aim_init*/ dllobj = (AIMSAMPLE*)$GETINITAREA(argv); if(!dllobj){ /* error handling processing */ return -1; } if(dllobj->status != 1){ strcpy(dllobj->message, "Call sequence is invalid."); 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; }
-
Association with a call from the access definition file
This example outputs the array data acquired by DllFunc1 to DllFunc2 in reverse order. If DllFunc1 and DllFunc2 are not executed in this order, the script will be interrupted.
#AssetInformationManager HTML 0005 [VAR] DLLOBJ DATA STATUS [ARRAY] ARY1 ARY2 [SET_VALUE] DLLOBJ = $DLLLOAD('jamsample.dll') STATUS = $GETSTATUS() [IF] STATUS != NORMAL [THEN] [SET_VALUE] #error handling processing $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)
- Output result:
-
3
2
1
-