Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: DllCall with structures
I am not looking for a workaround for accessing the data (like sendkeys, OLE, DDE, etc). The examples I have are C and VB, but I would rather be in WB. I have the DLL call names, and otherwise am OK with using other calls, but the structure is where I am stuck.
The structure is something like this:
typedef struct xgroup { UINT16 nodes; /* # slots */ EHANDLE *eh; /* ptr to array of node handles */ INT32 key; /* key to be used for read/write */ INT16 detect_changes; /* Detect value changes */ INT16 refresh;/* picture refresh rate */ /* Event and callback fields */ INT32 app_event_index; /* osx application event index */ UINT32 app_event_hdl; /* osx application event handle */ VOID (*callback)(INT16,INT32);/* application callback address */ INT32 cb_hdl; /* application callback data */ } *GNUM;The calls are something like this:
GNUM x_define_group(UINT16 n_nodes, INT16 detect_changes ); VOID x_delete_group(GNUM gnum);
If it is zero it failed. Non-zero is probably ok.
Then armed with that number (x) ? And careful counting and IntControl 32 you can read the buffer.
To read the data at offset 4, use x+4.
Normally, structures have to be dealt with by allocating a binary buffer, getting the address of the binary buffer's data storage area and then passing the address as a "long" value to an API function via DllCall().
In your case, though, if you don't want to touch the contents of the structure then you will have an easier time. Just declare the return value of the first function to be called via DllCall() as a long integer. Then, take the return value from that function and pass it to the second function as a long integer value. It is simply a pointer to a chunk of memory allocated by the first function so you should be able to do this w/o any problems.
Once caveat to be aware of, however, is that if the memory that the pointer identifies is static memory in the DLL that provides the functions then you cannot simply use DllCall() by itself with a DLL name to make the 2 successive calls to functions in the DLL. Instead, you will need to use DllLoad(), DllCall(), DllCall() and then DllFree(). This is necesary because if you call DllCall() multiple times and specify only a DLL Name [instead of a DLL Handle] then the DLL that provides the functions will be repeatedly loaded, called and then unloaded for each time that DllCall() is used. Using DllLoad() will force the DLL to remain in memory regardless of how many times that DllCall() is used; use DllFree() to then unload the DLL that was loaded with DllLoad().
On the same subject of whether or not a pointer returned by DllCall() is still valid to pass in in as a parameter value in another call to DllCall() is the subject of heap allocated memory. If any functions in the DLL allocate memory from the heap and return pointers to it then the DLL probably supplies at least one function in it that is used to free up this heap allocated memory when you no longer need it. It is generally not safe for one module [e.g. the WinBatch interpreter] to call free() for heap memory allocated in a different module [e.g. a DLL being used via DllCall()]. If you fail to free up memory that is allocated by functions in a DLL and returned to you as a pointer value then this memory will be allocated & lost until your script exits.
Article ID: W15133
File Created: 2002:09:05:13:49:52
Last Updated: 2002:09:05:13:49:52