Я пытаюсь создать DLL-оболочку C для взаимодействия с коммерческой DLL, написанной в соответствии с соглашением о вызовах CDECL, чтобы ее можно было связать с существующими программами, написанными в Excel VBA (следовательно, с использованием соглашения о вызовах STDCALL).
У меня точно такая же проблема, вероятно, после попытки очень похожих вещей. Я пробовал использовать mingw (g cc & g ++, 32 и 64 бит) и cygwin g cc (g cc & g ++ 32 & 64 бит). Не повезло.
Я подозреваю, что проблема с компиляцией или компоновщиком, поскольку некоторые комбинации компилятора создают DLL, которые просто не распознаются VBA (хотя они могут быть вызваны заглушкой exe), выдавая ошибку 53-DLL не найдено. Другая комбинация приводит к другой ошибке (загрузка DLL с 48 ошибками), конечно, с тем же кодом.
Я использую Windows 10 64 бит с Office 64 бит.
Это оболочка . 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
из 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
И 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
Другие полезные данные:
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
Забыл добавить, что --add-stdlib-alias, похоже, ничего не делает: символы декорируются в DLL независимо от наличия этого флага .