Writing a Windows STDCALL DLL with Mingw64 or Cygwin compilers

百般思念 提交于 2021-01-29 20:14:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!