WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

DllCall Information

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

DllCall with Structures

Keywords: 	 DllCall with structures

Question:

I have some DLLs I need to call as part of a WinBatch program. The first call defines a structure and other calls give me access to data. The problem I have is how to handle the definition call that returns a structure. Then that structure is fed to other calls. How do I do this?

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); 

Answer:

The DllCall returns a pointer to a structure. So you get the pointer which will be a 32 bit number (maybe negative - no worry).

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