问题
I am trying to create a C wrapper DLL to interface a commercial DLL written with the CDECL calling convention, so that it can be interfaced with existing programs written in Excel VBA (hence using STDCALL calling convention).
I have exactly the same issue, probably after trying very similar things. I have tried using mingw (gcc & g++, 32 & 64 bits), and cygwin gcc flavors (gcc & g++ 32 & 64 bits). No luck.
I suspect an issue with the compilation or linker, as some combinations of compiler produce DLL that are just not recognized by VBA (although they can be called by a stub exe) throwing an error 53-DLL not found. Other combination give another error (48-error loading DLL), of course with the very same code.
I am using Windows 10 64 bits with Office 64 bits.
This is wrapper.c:
#include "wrapper.h"
#include <windows.h>
#include <stdio.h>
#ifdef cplusplus
extern "C"
{
#endif
PCNC_EXPORT void __stdcall WrFreeString(char* str)
{
//Memory
return FreeString(str);
}
PCNC_EXPORT int __stdcall WrGetVer()
{
return GetVer();
}
PCNC_EXPORT char* __stdcall WrGetLibPath()
{
return GetLibPath();
}
// snip ___
PCNC_EXPORT BOOL __stdcall DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#ifdef cplusplus
}
#endif
wrapper.h:
#include "PlanetCNCLib.h"
#include "PlanetCNCLibTypeDef.h"
#ifdef cplusplus
extern "C"
{
#endif
PCNC_EXPORT void __stdcall WrFreeString(char* str);
PCNC_EXPORT int __stdcall WrGetVer();
PCNC_EXPORT char* __stdcall WrGetLibPath();
#ifdef cplusplus
}
#endif
from PlanetCNCLib.h:
#ifndef __PlanetCNCLib_H__
#define __PlanetCNCLib_H__
#include "PlanetCNCLibTypeDef.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef PCNC_EXPORT
# ifdef _WIN32
# define PCNC_EXPORT __declspec(dllexport)
# else
# define PCNC_EXPORT __attribute__((visibility("default")))
# endif
#endif
// etc
And the Makefile:
#CPP=/usr/bin/i686-w64-mingw32-g++.exe # doesnt work (err 48 err loading DLL)
#CPP=/usr/bin/x86_64-w64-mingw32-g++.exe # doesnt work (err 53 DLL not found)
#CPP=/usr/bin/i686-pc-cygwin-g++ # doesnt work (err 48 err loading DLL)
#CPP=/usr/bin/x86_64-pc-cygwin-g++.exe # doesnt work (err 53 DLL not found)
#CPP=gcc # doesnt even compile
#LD=/usr/bin/i686-w64-mingw32-ld.exe
#LD=/usr/bin/x86_64-w64-mingw32-ld.exe
LD=$(CPP)
LDFLAGS=-shared -L/usr/lib -L./lib/ -Wl,--add-stdcall-alias #--kill-at
CFLAGS=-c
all: PlanetCNCWrapper.dll
wrapper.o:PlanetCNCLib.h PlanetCNCLibTypeDef.h wrapper.c
$(CPP) -o $@ wrapper.c $(CFLAGS)
PlanetCNCWrapper.dll:wrapper.o
$(LD) $(LDFLAGS) -o $@ $? -L./lib/ lib/PlanetCNCLib64.lib -lPlanetCNCLib64
clean:
rm -f *.o *.e *~ .*~ *stackdump PlanetCNCWrapper.dll
Other useful data:
Windows Version 1909 (OS Build 18363.778)
System type: 64-bit operating system, x64-based processor
Microsoft Excel for Office 365 MSO (16.0.11929.20708) 64 bits
i686-w64-mingw32-g++ (GCC) 9.2.0
x86_64-w64-mingw32-g++ (GCC) 9.2.0
i686-pc-cygwin-g++ (GCC) 6.4.0
x86_64-pc-cygwin-g++ (GCC) 9.3.0
Forgot to add that the --add-stdlib-alias doesn't seem to do anything: symbols get decorated in the DLL regardless of the presence of this flag.
来源:https://stackoverflow.com/questions/61458074/writing-a-windows-stdcall-dll-with-mingw64-or-cygwin-compilers