views:

104

answers:

3

Hello

I'm trying to create a DLL that will later be used in Inno Setup. I managed to create a DLL using Pelles as an IDE, with the following code:

#include <windows.h>

__declspec(dllexport) int sumT(){
   return 2;
}

Then I call map the DLL to a function in Inno Setup, using the following Delphi code:

function Hellow() : Integer ;
external 'sumT@files:yyy.dll stdcall';

It works as expected, returning 2. I can also call it from rundll32.exe - if I add a MsgBox in the DLL, it will appear, proving that everything works as expected.

Now the problem starts when I try to pass a value to the DLL, like that - for example:

#include <windows.h>

__declspec(dllexport) int sumT(int sumTah){
   return sumTah;
}

It stops working! In Inno Setup, I gives me the message:

"Runtime Error (at -1:0)"

And if I try rundll32.exe, I get:

Error in yyy.dll

Missing entry:sumT

I'm not going to paste the Delphi code here, because I virtually tried everything, same thing with the C code, I tried using __stdcall instead, declaring the argument as INT, UINT... and other things I forgot.

I also looked up the MSDN, but could not find anything pertaining to this particular problem.

So, can anyone help?

Thanks

EDIT: I am compiling in C, so no need for "extern".

+1  A: 

If you compile with a C++ compiler, the function name gets mangled so that it contains data about the arguments. The solution is to do something like:

extern "C" __declspec(dllexport) int myfn();

and then reference it as _myfn. The extern "C" tells the compiler to not mangle the function name. This does not work with templated functions, classes or overloaded functions.

reece
Thanks. I forgot to mention that I am already compiling in C, so no need for "extern" (AFAIK). But the function does get exported as _sumT@4, so you were right about the underscore. I fixed that by setting a compiler option ("Undecorate Exported stdcall functions").
Rolf
stdcall functions add the number of bytes that the stack is taking up to the end (the @4 in your case, here); leaving them undecorated may cause stack corruption issues. You probably want to mark it with the cdecl calling convention, which will always leave the call as `_sumT`.
reece
+1  A: 

__declspec(dllexport) int sumT(int sumThah){
return sumTah;

looks like a typo or your error....

François
Thanks! I fixed that.
Rolf
+2  A: 

The exported name probably doesn't match what you think it looks like. Use dumpbin.exe /exports on the DLL to see the actual exported name. Use extern "C" to suppress name mangling.

Also, you have to declare this function __stdcall, that's what your Delphi declaration said. The default is __cdecl. That will fail when you start passing arguments.

Hans Passant
Thanks for the Tip about using dumpbin.exeIt turns out the function is exported as "_sumT@4"I found an option in the compiler that says "Undecorate Exported stdcall functions" (In Project options -> Compiler). That should do it. BTW __stdcall doesnt seem to work.
Rolf