Написание Windows STDCALL DLL с помощью компиляторов Mingw64 или Cygwin - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь создать 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 независимо от наличия этого флага .

...