- NSIS Discussion
- How to System::Call DLL function with reference?
Archive: How to System::Call DLL function with reference?
dbarrett
18th July 2006 04:01 UTC
How to System::Call DLL function with reference?
I have a DLL with an exported function with the following signature:
extern "C" __declspec(dllexport) HRESULT Run4( HINSTANCE, HINSTANCE, HINSTANCE, LPSTR, int, bool& )
How do I call this function and receive the 'bool&' back into the NSIS script?
The best I can come up with is:
System::Call "MyDLL::Run4( i 0, i 0, i 0, t '', *i .r4 ), i.r3" ? u
But the DLL segfaults when it tries to write to the boolean reference. I assume this means I'm incorrectly passing in the reference to $4. I've tried this:
System::Alloc 4
Pop $4
System::Call "MyDLL::Run4( i 0, i 0, i 0, t '', *i .r4 ), i.r3" ? u
And this:
System::Alloc 4
Pop $4
System::Call "MyDLL::Run4( i 0, i 0, i 0, t '', i .r4 ), i.r3" ? u
And this:
System::Call "MyDLL::Run4( i 0, i 0, i 0, t '', *i 0 r4 ), i.r3" ? u
But no effect. Can you see what mistake I'm making, or is what I'm trying to do not possible?
-david
PS: It works fine if I comment out the line assigning the value to the 'bool' in the DLL, so I do believe it's been narrowed down to this one issue.
Joel
18th July 2006 04:22 UTC
Let's see:
extern
"C"__declspec(dllexport)HRESULTRun4(HINSTANCE,HINSTANCE,HINSTANCE,LPSTR,int,bool&)
Now converted to system syntax:
System
:Call'MyDLL::Run4(i0,i0,t"",i0,*i.r1)i.r0'
I don't have the dll, so I can't test it.
dbarrett
18th July 2006 04:39 UTC
Alas, no luck. Every time it just segfaults when I try to write to the 'bool&' parameter. :(
Afrow UK
18th July 2006 11:11 UTC
Can't you use BOOL with TRUE and FALSE?
It's just an int with 0 or 1 then.
-Stu
dbarrett
18th July 2006 20:50 UTC
Unfortunately I can't change the function signature for backwards compatability reasons. Were it up to me I'd just return 'true' or 'false' in the return value. Unfortunately, I'm stuck with a reference to a 'bool'.
Now, I *think* a reference looks just like a pointer on the stack, and is just treated special by the compiler. Thus I'd assume the standard pointer semantics of the System::Call would work. But unfortunately I can't get them too. Can you come up with any other variations I might try?
-david
Joel
19th July 2006 02:25 UTC
Can you come up with any other variations I might try?
Can you post the DLL?
dbarrett
19th July 2006 09:38 UTC
Ok, I'll put together a DLL with the same function signature and post a link here. Thanks for all your help on this.
In the meantime, I've decided to temporarily drop the backwards compatibility requirement and go with a function that's:
HRESULT Run( )
Much simpler, works like a charm. However, now I've discovered another hangup: the DLL filename contains a hyphen, and that seems to muck it up. Specifically, my code is:
System::Call "$2::Run( ) i.r3 ? u"
So far as I can tell, this works great so long as $2 is a purely alphabetical name (eg, "MyDLL"). But a DLL name with hyphens (eg, "MyDLL-1.2-3") appears to screw it up.
Can you recommend any way to pass in a hyphenated DLL name?
Again, thanks for all your help with this.
-david
kichik
19th July 2006 17:12 UTC
Originally posted by dbarrett
Can you recommend any way to pass in a hyphenated DLL name?
Extract it with a hyphen-less name. You can even use GetTempFileName.
dbarrett
19th July 2006 23:37 UTC
Eureka! I figured out the filename issue. My DLL filename is of the following form:
MyDLL-X.YYY-ZZZ.dll
And I was calling as follows:
System::Call "MyDLL-X.YYY-ZZZ::Run( ) i.r3 ? u"
However, the 'LoadLibrary' Win32 function only appends the ".dll" to the end when searching if the name passed in doesn't have an extension. And it assumed my DLL had the extension "YYY-ZZZ" and thus failed. The solution is to explicitly indicate the ".dll" extension in the System::Call as follows:
System::Call "MyDLL-X.YYY-ZZZ.dll::Run( ) i.r3 ? u"
So, that fixes that up. Next I need to get the "bool&" function signature to work, but this lets me keep moving forward. Thanks!
-david