Call DLL Function Responsibilities

Got a problem you cannot solve? Try here.
mihai
Posts: 34
Joined: Fri Nov 29, 2013 3:53 am

Call DLL Function Responsibilities

Postby mihai » Thu May 15, 2025 2:43 am

Hello,

For my own DLL export function that I'm calling with "Call DLL Function", whose responsibility is it to allocate and later free the memory for an output parameter of type "pointer to UNICODE string", that the export function writes to?

If it's the caller's responsibility, then should one use "Set Variable" with a large enough placeholder string?

The official documentation only states:
If a variable is provided in this field, and the parameter is being passed to the function by reference, the passed variable will contain the new value of the parameter.


Thanks in advance,
Mihai

JohnGaver
Posts: 230
Joined: Mon Feb 05, 2024 6:15 pm

Re: Call DLL Function Responsibilities

Postby JohnGaver » Thu May 15, 2025 9:23 am

Excellent question!

If you need Call DLL Function to allocate memory, please choose one of the following fields:

Code: Select all

Allocated string buffer (MAX_PATH)
Allocated UNICODE string buffer (MAX_PATH)

Either of the above options will allocate memory of MAX_PATH (255) character length before passing the address of the allocated string pointer to the called function (ex: GetTempPath). The function may then safely (over)write this memory and return the requested data to the caller, namely Call DLL Function; which would then update your passed in script variable with that received value.

OTOH, if you're passing an already-allocated string-buffer to another kind of API, then you'd just use one of these fields:

Code: Select all

pointer to string
pointer to UNICODE string

These options would basically take the script variable you're passing in, and relay that onward to the API you're calling (ex: RemoveDirectory). There's no character length limitation - however long your existing variable is, it'll be passed accurately.

If the called function attempts to overwrite this memory, however, bad things will happen (with the issue typically being entirely invisible until one of your C-level suite are doing a high profile demonstration at one renown trade expo or the other).

So the length of the script variable you initialize with Set Variable never really matters:

If you're passing that string as a constant to the API function you're calling, you're more interested in passing the actual data than its particular length - and the entire string will be passed properly, null terminated, to its destination.

If you're passing that string as a buffer for the API function you're calling to (over)write, you again don't need to specify any particular length in Set Variable, because all string pointer buffers will be hard-coded with a size that can accommodate up to MAX_PATH (255) characters - irrespective of how long your actual script variable is at that point.

Of course, you still need to ensure the script variable has been declared before you call Call DLL Function.

Call DLL Function itself is an InstallAware plug-in. It needs all script variables you pass to it to have been pre-initialized, regardless of where they are used (either as constants or as variables).

Zero length, empty strings are perfectly fine to initialize your script variables with, before passing those script variables to any InstallAware plug-in you're needing.

This is exactly the same with Call DLL Function, irrespective of any API/memory issues we've been discussing here on this thread.

Built-in commands don't have this pre-initialization requirement, simply because they're smart enough to dynamically define new variables where needed.

Plug-ins cannot do this, because the plug-in spec doesn't allow plug-ins to define new variables on-the-fly - plug-ins may only receive the list of existing variables (together with their values, of course), and update them.

Two wrap it all up, here's example script code that calls Call DLL Function on GetTempPath with the necessary variable pre-initializations - just "SELECT ALL", copy, and paste directly into your InstallAware IDE script editor to try it out:

Code: Select all

~InstallAware Clipboard Data~
~MessageBox~
~{82FE6225-859C-4BA8-B4DD-E5EB545DDB2C}~
~POINTERTOSTRING, APIRESULT~
~$POINTERTOSTRING$$NEWLINE$$APIRESULT$~
~0~
~1~
~~
~Call DLL Function~
~{81D76E26-FDCD-486C-9ACE-5442AB20CEBF}~
~kernel32.dll,GetTempPath,"double word",APIRESULT,"double word",255,"allocated UNICODE string buffer (MAX_PATH)",$POINTERTOSTRING$,$~
~mIDEFunc.dll\mEXEFunc.dll~
~Set Variable~
~{4A8873F7-23FA-4B91-A7B7-826B8CC984C6}~
~APIRESULT$MYAH$MYAH$FALSE~
~~
~Set Variable~
~{F9C81A67-71E9-44FF-BB40-38B352C1D1E5}~
~POINTERTOSTRING$MYAH$MYAH$FALSE~
~~
John Gaver
InstallAware Skunkworks
InstallAware Multi Platform - Liberating DEB/RPM/PKG/MSI(X) into universal native setups!
Get your free copy today - https://www.installaware.com/installaware-multi-platform.htm

mihai
Posts: 34
Joined: Fri Nov 29, 2013 3:53 am

Re: Call DLL Function Responsibilities

Postby mihai » Fri May 16, 2025 1:24 am

Thanks John for the very detailed reply, that clarified a lot!


Return to “Technical Support”

Who is online

Users browsing this forum: No registered users and 18 guests