Archive: Calling a DLL


Calling a DLL
Calling a DLL from within NSIS:

Why is this not working?

==============================
SetPluginUnload alwaysoff

Function loadDll

SetOutPath $TEMP
File XmlToIni.dll ; copy dll
StrCpy $0 '$TEMP\file.ini'
System::Call 'XmlToIni::SaveIniToFile(t) l(r0) r1'

SetPluginUnload manual
System::Free 0

FunctionEnd
==============================

The interface within the DLL to call is:

long SaveIniToFile(char* szFileName)

And returns back a long.


Some notes:
1. SetOutPath $TEMP. Outputing to the users Temp. dir., right?
2. System::Call 'XmlToIni::SaveIniToFile(t) l(r0) r1'. System, mostly, call the functions from DLLs APIs inside $SYSDIR folder.
3. System::Free 0. You should use:


System::Free $0

Recommendation:
Try to call directly your DLL, avoiding the system plugin. See web archive about examples of plugins.

System::Free 0 is right, there is no need to change it. You can however remove SetPluginUnload alwaysoff, SetPluginUnload manual and System::Free 0 because it's not really needed when you can System.dll just one time.

You are missing a dot before r1, the result will never go into $1. To figure out what's wrong, more details are needed. Most importantly, what exactly isn't working.


OK getting a message back in $1, which is error, which is a good start.

But the DLL is not running as it should create a file called file.ini in the temp area.

SetOutPath $SYSDIR ; create temp directory
File XmlToIni.dll ; copy dll there
StrCpy $0 '$TEMP\file.ini'
System::Call 'XmlToIni::SaveIniToFile(t) l(r0) .r1'


Lobo >> System, mostly, call the functions from DLLs APIs inside $SYSDIR folder.

What do you mean? Does it mean that we should always append the directory where a given DLL is located?

>> System::Free $0

What is this System::Free used for, really? I'm confused about why I need SetPluginUnload alwaysoff + SetPluginUnload manual + System::Free. Could you tell us why we need those three statements when using the System plug-in?

>> Try to call directly your DLL, avoiding the system plugin. See web archive about examples of plugins.

What do you mean with "call directly"? What other way is there to call a DLL from NSIS besides the System plug-in?

b_avery >> But the DLL is not running as it should create a file called file.ini in the temp area.

Not sure this is the cause, but is there a space between "l" and "(r0)"? I know there's a space missing in the documentation on the System plug-in. Try this instead:


System::Call 'XmlToIni::SaveIniToFile(t) l (r0) .r1'
^ here, a space


Thank you :-)
Fred.

Nope, still an error :-(


I don't know, but generally the error return is an integer (i), unless it's specified.

And about the input, see the documentation if the input is A pointer to buffer or variable where you have to add a pointer, and A pointer to string where you don't.

So I suggest:

System::Call'XmlToIni::SaveIniToFile(t)i(r0).r1'

OR

System::Call'XmlToIni::SaveIniToFile(t)i(*r0).r1'


No still the same.

Yes the routine does come back with a Long

Here is the call details:

long SaveIniToFile(char* szFileName)


if this will not connect I could try:

long SaveIniToFile(LPCSTR szFileName)


What do you mean? Does it mean that we should always append the directory where a given DLL is located?
That the DLL, called by system plugin, must be in the $SYSDIR for easy location and execution.
What is this System::Free used for, really?
Release or free the resources use by the functon called by the system plugin. We don't want memory leaks...
I'm confused about why I need SetPluginUnload alwaysoff + SetPluginUnload manual + System::Free. Could you tell us why we need those three statements when using the System plug-in?
I don't use them, but in the DOCs you might find the awnser. As my way, I don't really need them.
What do you mean with "call directly"? What other way is there to call a DLL from NSIS besides the System plug-in?
Well... an example of calling directly is the system plugin. Maybe you could find a way to use your plugin without using the system plugin.

My DLL is still not working from NSIS :-(


Some corrections:

That the DLL, called by system plug-in, must be in the $SYSDIR for easy location and execution.
It doesn't have to be in $SYSDIR. On the contrary, it looks in the current directory first.
Release or free the resources use by the function called by the system plug-in. We don't want memory leaks...
System::Free doesn't free resources used by the System plug-in. It frees resources allocated using the System plug-in using System::Alloc or the special System::Call syntax. If you pass $0 to it, it will try to free the memory pointed to by $0 which is a bad idea unless you've saved an address of some allocated memory in it. If you use System::Free 0 it will simply do nothing. Why this is needed will be clear once you read about SetPluginsUnload.
Well... an example of calling directly is the system plug-in. Maybe you could find a way to use your plug-in without using the system plug-in.
You can only call specifically designed DLLs directly from the NSIS script using the DLLName::FuncName syntax. See Contrib\ExDLL for a skeleton of such a DLL.

As for the thread starter's problem, some details are still missing... The exact error returned, whether or not the DLL is called (put a message box on the top of the function, don't rely on file creation to find out) and the new line used to call the function.

I have looked all over for "Contrib\ExDLL for a skeleton of such a DLL" but can't find where you are refering to. Please can you help me?


How can we help if we don't know the type of error.
Maybe you can attach your script will be helpfull.


Contrib\ExDLL contains header file that allow to create a NSIS plug-in.


>> I have looked all over for "Contrib\ExDLL for a skeleton of such a DLL" but can't find where you are refering to

It means that you should look in the directory where you installed NSIS. There are a bunch of sub-directories, one of them being Contrib. You'll find a sub-sub-directory called ExDLL... which only contains source code, no documentation, so I doubt it'll help you much in solving your problem :-)

Personally, I'm more concerned about this :

>> You can only call specifically designed DLLs directly from the NSIS script using the DLLName::FuncName syntax

Does it mean that we cannot call any DLL we want using the System plug-in? What is the issue?

And if someone has successfully called a COM control through the System plug-in, I'm still interested in an example :-)

Thx
Fred.


You can call any DLL using the System DLL. That quote refers to a direct call without the System plug-in.


Ah ok. I didn't know there was another way to call a DLL besides using the System plug-in.

How do I do this, and what are the avantages/disadvantages?

Thx
Fred.


These DLLs are NSIS plug-ins, which you can find in the Plugins folder.

NSIS plug-ins can access the NSIS stack and registers and will automatically be extraced and removed by NSIS.

Examples of plug-in are InstallOptions, NSISdl, LangDLL etc.