1

My 32bit windows program is using default __cdecl calling convention. It is using Qt toolkit. I'm trying to use unamanged dll that is using __stdcall convention and exports only undecorated names.

dumpbin /exports library.dll
[...]
    00000000 characteristics
           0 time date stamp
        0.00 version
           1 ordinal base
         210 number of functions
         210 number of names

    ordinal hint RVA      name
[...]
          6   9D 0000361C OpenComm
[...]

I created .def file with decorated name mapping:

EXPORTS
    _OpenComm@8=OpenComm

As a result .lib has following export (notice the double underscore in front):

__OpenComm@8

Header file contains (notice underscore that I had to put there to match .lib):

extern "C"
{
int __stdcall _OpenComm(char *com, int Baudrate);
}

Program compiles fine but when I try to run it runtime linker gives me an error:

The procedure entry point _OpenComm@8 could not be located in the dynamic link library.

OK. Dll does not have my mapped name ... How can I solve this ? Can I rename exports inside compiled .dll ? :-)

1 Answers1

0

The problem is not the DLL, but the way you generated the .lib and how you write the header file.

Do not add an underscore the your function in the header file. The compiler/linker toolchain will automatically handle the underscore in the symbol.

Try

extern "C"
{
int __stdcall OpenComm(char *com, int Baudrate);
}

Now the .def file should have looked like this if you were using it at the time you build the DLL and .lib:

LIBRARY mylibrary
EXPORTS
    OpenComm

But since you generate the .lib only from the .def file, and the dll uses stdcall, you need to change your .def:

LIBRARY mylibrary
EXPORTS
    OpenComm@8 @6

This will effectively generate a .lib that exports _OpenComm@8 and will make your exe call the symbol with ordinal 6 in your dll. Note that if you update your DLL, you will have to check if any ordinals as changed using dumpbin and update your .def accordingly.

Benjamin T
  • 8,120
  • 20
  • 37
  • When I follow your advice I'm getting linking problems during compilation: error: LNK2019: unresolved external symbol _OpenComm@8 referenced in function ... My environment is Qt 5.8 and Visual Studio 2015 – Mariusz Zieliński Mar 03 '17 at 09:43
  • Try `__declspec(dllimport) int __stdcall OpenComm(char *com, int Baudrate);` – Benjamin T Mar 03 '17 at 09:50
  • It did not help : nexus.obj:-1: error: LNK2019: unresolved external symbol __imp__OpenComm@8 referenced in function ... – Mariusz Zieliński Mar 03 '17 at 10:11
  • @MariuszZieliński I've updated my answer to take into account the __stdcall in the def file. I suggest you take a look at http://wyw.dcweb.cn/stdcall.htm , this is a good read for this kind of topic. – Benjamin T Mar 03 '17 at 11:26
  • Benjamin. For the record - I didn't downwote your answer. I don't like when peple do that without leaving comment. I can't modify .dll file I have. It contains undecorated exports that in reality are __stdcall calls. Problem is to convince my program to do a __stdcall call to dll function using undecorated symbol and not _name@number. I can do that by loading library manually using QLibrary but it seems less elegant. – Mariusz Zieliński Mar 03 '17 at 12:22
  • During runtime .lib is not present anymore and there is no way to use ordinal numbers to call functions. I red somewhere that it is something from 16bit era. – Mariusz Zieliński Mar 03 '17 at 12:28
  • @MariuszZieliński Using ordinal numbers does not requires the lib to be present at runtime. Agreed that it is not a pretty way to solve your problem, but it looks like it is the only way. – Benjamin T Mar 03 '17 at 13:16
  • @MariuszZieliński An old question has already been solved using the solution I gave you: http://stackoverflow.com/questions/2393178/creating-an-msvc-import-library-from-a-dll-that-uses-stdcall – Benjamin T Mar 03 '17 at 13:20