0

I am maintaining some DLL for Windows that is delivered in 32 and 64 bit versions. It has been build with Visual Studio 2010, but for some reasons I recently changed to MinGW (7.3, also tried 9.2). For the 64 bit version everything seems to be ok, but the 32 bit version doesn't work when loaded in Python or LabView; both can load the DLL but don't find the functions. A simplified example:

// mydll.h
extern "C" __declspec(dllexport) int __stdcall myFunc( int x );

// mydll.cpp
#include "mydll.h"
int _stdcall myFunc( int x )
{
  return 2*x;
}

# test.py
import ctypes
lib = ctypes.windll.LoadLibrary('.\mydll.dll')
lib.myFunc.argtypes = [ctypes.c_int32]
print(lib.myFunc(1))

Commands, using MinGW 7.3 and Python 3.7.2 (32 bit):

> g++ -shared -o mydll.dll mydll.cpp
> python test.py
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print(lib.myFunc(1))
  ...
AttributeError: function 'myFunc' not found

The same code runs and prints "2" when compiled with MSVC-32bit or with MinGW-64bit.

Why doesn't it work with MinGW-32bit? I suspect it's an issue of the C name mangling: The exported symbol names of the DLL as reported by "dumpbin /exports mydll.dll" are _myFunc@4 (MSVC) and myFunc@4 (MinGW) - MinGW's output misses a leading underscore. As far as I understand, Python and LV expect the mangled names in the MSVC style (and hide the mangling in their user interface).

I have tried a couple of MinGW Options such as -Wl,-fleading_underscore, -Wl,--add-stdcall-alias, -Wl,--enable-stdcall-fixup to achieve compatible export names, but without success. One would expect that this is a common problem as the combination C/Python isn't really exotic, but I can't find any discussion of the problem on the net. What I am doing wrong?

Martian
  • 3
  • 3
  • Did you try `-Wl,--add-stdcall-alias` when building the DLL? – Brecht Sanders May 18 '22 at 22:06
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community May 19 '22 at 02:32
  • @BrechtSanders: Yes I did, the result was an extra exported symbol "myFunc" (completely undecorated) that also has not been found. – Martian May 19 '22 at 12:19
  • @Community: Thanks for the hint; I'll try to give a complete example. – Martian May 19 '22 at 12:23

1 Answers1

0

I ran into the same problem. Theoretically dlltool might be able to help somehow, with its --add-stdcall-underscore option, but I couldn't get that to work.. it sucks that MinGW's ld doesn't have that option.

Anyway, I found another solution: Create your own mydll.def file with aliases, like

LIBRARY "mydll.dll"
EXPORTS

myFunc@4
_myFunc@4 = myFunc@4

myFunc2@42
_myFunc2@42 = myFunc2@42

(Using the gendef tool on your current state of the DLL could help to get an initial version of that .def, but it was a bit buggy for me, generating both myfunc@4 and myfunc@4@4 lines)

Then build the DLL with g++ -shared -o mydll.dll mydll.def mydll.cpp

You could also add -Wl,--add-stdcall-alias to also automatically create aliases without the @4 at the end (might be necessary to make GetProcAddress(myDllHandle, "myFunc"); work?), and it may be a good idea to use --static-libgcc so your DLL works without bundling libgcc_s_dw2-1.dll.

Daniel
  • 146
  • 1
  • 3
  • Thanks for your hint to the dlltool. As far as I understand, --add-stdcall-underscore is meant for the creation of import libs that won't help in my case. But dlltool -z also creates a def file that seems to be correct. We will try to write some sed script to patch that file automatically to add aliases that match Microsofts conventions. This doesn't look very elegant but might be a solution. – Martian Jun 20 '22 at 15:42