- NSIS Discussion
- System plugin and passing parameters to dll
Archive: System plugin and passing parameters to dll
pps
6th November 2006 12:06 UTC
System plugin and passing parameters to dll
Hello.
I've got problem with passing parameters to DLL.
I need to pass something like char** (just like parameters table in regular c++), but after some tries I've given up.
I'm sure that this is not correct way:
System::Call '*(t R3) i.R2'
System::Call '*(i R2) i.R1'
System::Call 'advapi32::StartServiceA(i r5, i $R4, i $R1) i.r6 ? e'
System::Free $R1
System::Free $R2
Pop $0 ; error code
In StartServiceA:
$R1 should be a pointer to table of pointers to null-terminated strings.
$R4 should contain number of strings.
How can I make structure like this and how can I count $R4 value (assuming I have only regular string with spaces in $R7)?
And another question. Option '? e' pops an error code to stack. Is the order of 'Pop' and 'Free' important (in other words: does '::Call*(...)' and '? e' use the same stack)?
Thanks,
pps
6th November 2006 15:21 UTC
Maybe this way:
System::Call '*(t R3, n) i.R1'
System::Call 'advapi32::StartServiceA(i r5, i $R4, i $R1) i.r6 ? e'
System::Free $R1
$R3 contains first (and only one in this example) parameter.
$R4 = 1
If there will be more parameters, this will looks like:
System::Call '*(t R3, R6, R7, R8, n) i.R1'
Am I wrong?
I've tried to start notepad as a service (successful), but the parameter is ignored. The idea was to run notepad with filename :
c:\windows\system32\notepad.exe c:\test.txt
The notepad is starting just fine, but the file isn't opening (the parameter isn't recognized).
Any ideas?
kichik
6th November 2006 20:47 UTC
Almost. You need to use specify a type for each member of the structure. Use `t` before R6, R7 and R8. There's also no need for that last `n`.
System::Call '*(t R3, t R6, t R7, t R8) i.R1'
The order of System::Free and Pop is not important, even though they use the same stack. System::Free only pops on item from the stack, so it won't pop the error.
pps
7th November 2006 16:34 UTC
Thanks for help :)
And what about creating tables of structures?
For example I want to create structure like this:
typedef struct {
int a;
char t[10];
__int64 b;
double x;
char *p;
} myStruct;
Is the only way to do that this way (just 2-elements array):
System::Call '*(i 1, t&10 "asdfb", l 100, ???, t* n, i 7, t&10 "qwerty", l 1991, ???, t* r2) i.r1'
And what about float numbers?
I've successfully used this method to pass address of int[][] to dll, but is there any simplier method?
2 weeks isn't enough to fully explore NSIS' capabilities... ;)
Thanks again,
Comm@nder21
7th November 2006 19:47 UTC
2 weeks isn't enough to fully explore NSIS' capabilities...
believe me: 2 years aren't either :D
kichik
7th November 2006 20:11 UTC
It depends if you're defining an array of structs or struct pointers. If those are pointers, allocate each structure using the same method you allocate the array and allocate the array with all of the pointers. If it's just an array, the method you've shown should work. Just don't forget to mind alignments.
Probably the easiest method of seeing where everything should be placed is writing a simple C program that'd print the offsets of every member.
pospec
12th May 2008 09:55 UTC
OK, and how can I System::Call with float parameter, please?
kichik
12th May 2008 13:51 UTC
You can't. It doesn't support floats. The Math plug-in, however, has support for floats.
pospec
12th May 2008 13:55 UTC
So there is no way how to System::Call my DLL exported 'float func(float x)' without writing some "wrapper"?
kichik
12th May 2008 14:03 UTC
That's correct.
pospec
12th May 2008 14:06 UTC
Sad but true. And why can't System plugin convert from string to float and pass it to function?
kichik
12th May 2008 19:24 UTC
Because it doesn't that functionality built-in. Floats are a pin to handle.