- NSIS Discussion
- Calling a DLL
Archive: Calling a DLL
b_avery@yahoo.c
24th April 2004 11:11 UTC
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.
Joel
24th April 2004 15:27 UTC
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.
kichik
24th April 2004 15:44 UTC
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.
b_avery@yahoo.c
25th April 2004 09:36 UTC
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'
fredtheman
25th April 2004 11:54 UTC
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.
b_avery@yahoo.c
25th April 2004 12:59 UTC
Nope, still an error :-(
deguix
25th April 2004 14:25 UTC
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'
b_avery@yahoo.c
25th April 2004 15:10 UTC
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)
Joel
25th April 2004 15:12 UTC
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.
b_avery@yahoo.c
25th April 2004 19:20 UTC
My DLL is still not working from NSIS :-(
kichik
25th April 2004 19:23 UTC
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.
b_avery@yahoo.c
25th April 2004 19:46 UTC
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?
Joel
26th April 2004 15:01 UTC
How can we help if we don't know the type of error.
Maybe you can attach your script will be helpfull.
Joost Verburg
26th April 2004 16:49 UTC
Contrib\ExDLL contains header file that allow to create a NSIS plug-in.
fredtheman
26th April 2004 16:55 UTC
>> 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.
Joost Verburg
26th April 2004 16:58 UTC
You can call any DLL using the System DLL. That quote refers to a direct call without the System plug-in.
fredtheman
26th April 2004 17:06 UTC
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.
Joost Verburg
26th April 2004 18:26 UTC
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.