Archive: Using System plug-in to load external dll file


Using System plug-in to load external dll file
Hi Guys,

My first step in such a community.

I'm currently trying to call a function from external ddli file usinc the system plug-in.
Unfortunately, I always have a returning error. I can't even checked whether the DLL function is called, or whether the DLL is loaded or not.
Here is my Current code :

SetOutPath $TEMP\MyDLL ; Storing my DLL in tmp folder
File MyDLL.dll ; DLL file coopy

;bool MyFunction (const char* sValue) ; The main function declaration in my C Code

${NSD_GetText} $NomTextBox $0 ; Retrieving string value from textbox

SetOutPath $TEMP\
System::Call "MyDLL::MyFunction(*t r0) i .r1"
MessageBox MB_OK $1

If someone has any idea to help me... you're welcome !!

Cheers


You're extracting the dll to $TEMP\MyDll, then trying to run it from $Temp\.

Also, you should use $PLUGINSDIR as your temp directory, not $TEMP.



InitPluginsDir
SetOutPath $pluginsdir
File MyDLL.dll
...
System::Call "MyDLL::MyFunction(m r0) i .r1"


You don't need *, t or m is enough (t is LPTSTR, m is always char*)
If MyFunction is cdecl and not stdcall, you need to tell system about it with the "?c" suffix

Hello Anders

Thanks for reply. I think I need to use the "?c" suffix. sorry, but can you clarify me where and how to use such a parameter ? :)

Thx !


Thanks ...

But still have the same trouble.
Just tried the Anders' solution below...


Any dependencies missing? Have you made sure the function is exported correctly?

Stu


Hello !

I checked the main dependencies, and nothing is missing.
Here is the portion of code , where the function is declared : (Hope this can help)

extern "C" int __declspec( dllexport ) Dummy()
{
::MessageBox(NULL, _T("kjoljkljljl"), _T("kjhjkhkjh"), 0);
return 1;
}

extern "C" bool __declspec( dllexport ) MyFunction (const char* sValue)
{
return AnotherFunction (sValue);
}

I also add a dummy function to make test, but nothing seems to work.

Here is also the NSIS code :

InitPluginsDir
SetOutPath $PLUGINSDIR
File MyFile.dll
SetPluginUnload alwaysoff

${NSD_GetText} $NomTextBox $0 ; where I ask the user to fill a string value

System::Call 'MyFile::MyFunction(m r0) i .r1 ?c'

MessageBox MB_OK $1

I just can't stand it no more !!!!
Please help, you'd make me happy for the day ;o)

Thanks by advance



!define PLUGINNAME MyFile
!define PLUGINEXPORT MyFunction

SetOutPath $pluginsdir
File ${PLUGINNAME}.dll
System::Call 'kernel32::LoadLibrary(t "$pluginsdir\${PLUGINNAME}")i.r0'
System::Call 'kernel32::GetProcAddress(i r0,m "${PLUGINEXPORT}")i.r1'
MessageBox mb_ok $1
System::Call 'kernel32::FreeLibrary(ir0)'


If this fails, your plugin is broken or the exported function name is decorated. Open it in Dependency Walker and take a look.

To force cdecl, don't just specify "__declspec( dllexport )", use "__declspec( dllexport ) __cdecl"

First, thanks for your reply.

Just tried to make your modifications, and unfortunately, return value is 0; which means fail if I'm not wrong ...

I will try to check the way you call the DLL function, and investigate...

Btw, thanks for your support...


The DLL file is correctly loaded : Handle Value is not NULL...
But I've got a NULL value return, when attempting to call the function... something must be wrong with it...


well, it is impossible to go any further when we don't know anything about your compiler setup

so please use Dependency Walker or dumpbin and check the exports


Hello again ...

Well, I've uploaded my test Visual project here :
http://bsayakhom.free.fr/VisualProject_test2DLL.zip

Here is also the full NSIS project folder with other script required.

I don't know if this can help you to solve my problem, because I'm completely stuck right now, and as you said, I can't go further now....:igor:

If any good feedback, you're welcome.

PS : I'm currently building the Installer.nsi script


With the dll you posted:

outfile test.exe
requestexecutionlevel user
!define PLUGINNAME test2
!define PLUGINEXPORT MyFunction
section
initpluginsdir
SetOutPath $pluginsdir
File ${PLUGINNAME}.dll
System::Call 'kernel32::LoadLibrary(t "$pluginsdir\${PLUGINNAME}")i.r0'
System::Call 'kernel32::GetProcAddress(i r0,m "${PLUGINEXPORT}")i.r1'
MessageBox mb_ok $1 ;!=0
System::Call 'kernel32::FreeLibrary(ir0)'

System::Call '${PLUGINNAME}::${PLUGINEXPORT}(&i1 42)i.r0 ?cu'
MessageBox mb_ok $0 ;prints 42

SetOutPath $temp
sectionend


works fine, but just so you know
extern "C" char __declspec ( dllexport )__cdecl MyFunction (char sValue)
{
return (sValue);
}

is just handling a single character (byte), not a string.

Great , that works :
The requestexecutionlevel was missing, but adding this, function are correcly loaded.

I just have one question :
In the following command, <System::Call 'kernel32::GetProcAddress(i r0,m "${PLUGINEXPORT}")i.r1'>, do you really need to specify the "m" Attribute as output type near the function name ?

You must have understood that I'm little newbie, so sorry for the following question, bu for sure, if my function return a boolean, I have to specify int. type as return value right ?

I think I'm now on the good way, so thanks a lot for all the help you provided me with !!!


well, yes, you ALWAYS have to specify a type for each parameter, and the 2nd parameter to GetProcAddress is char*