Create a Mingw DLL to be used with a VB exe

2019-08-01 05:53发布

问题:

I cannot find any solution in the web that works for my case. I read in Microsoft Developer Network, problems from here and several wikis, but nothing, but after reading so many info and some of the in contradiction to others ... I have a mess!

My history:

1- I have to change a software already created in Visual C++ (a DLL) and I do not know which Visual Studio was used to compile it, this DLL was working with a Visual Basic program.

2- I success in changing the program to use another communication protocol (that was the change... easy) and I have used Visual Studio 2012, I had some .NET issues in my computer, but I correct them and my computer should be fine, well I debug the dll and was working perfectly in my computer, but whenever I take the DLL to another makes a Run time error 53 (does not find the file), what actually does not find is the MSVCP110D.dll library, I guess because is a VS 2012 library (compiler vc11.0 so looks like is because of it), so I decide the next step:

3- I decide to migrate it to Mingw, because I heard is possible to create dll compatible with VB exe, ok I install eclipse and mingw, and modify again my C++ code to adapt to Mingw compiler and libraries, now I create the dll, also the .def and library .lib (well I rename the extension to .a) first gave me an error that can not find the function name, then I put:

#ifdef __cplusplus
    extern "C" {
#endif

and the __stdcall (because the __cdecl is not for msvc, what I read), after this change the run time error change to 48 (I read this is a problem loading the DLL), I check is could be problem of the .def and try to create a new DLL with this .def usin the lib.exe and DUMPBIN from the VS 2012 compiler (but it does not work properly).

I comment all inside of my functions to just return the value 0, I remove the DllMain that there was (which is used for any program to find a entry point to initialise) but I commented because I do not initialise nothing, here I paste a bit of my code.

.h:

    #define DLL_TESTER VB // define whenever I use the dll with the VB.exe
    #ifdef DLL_TESTER
        #ifdef DLLTRY_EXPORTS
//after I use the option -DCPDLLEXPORT to define and set the value to __declspec(dllexport)
            #define ADDCALL __declspec(dllexport)
        #else
            #define ADDCALL __declspec(dllimport)
         #endif
         #define DLLTRY __stdcall
//this is supposly the correct one for VB.exe calls but try the __cdecl neither
    #else
//if is not with a VB.exe the tester would be a C application
        #define EXTDLLCALL __cdecl
        #ifdef DLLTRY_EXPORTS
            #define ADDCALL __declspec(dllexport) EXTDLLCALL
        #else
            #define ADDCALL __declspec(dllimport) EXTDLLCALL
        #endif
#endif

May the order is wrong, but I try lot of different orders and none working: __declspec(dllexport) before the return value (int) with the __stdcall and __cdecl next to it or in the other side of the return value, in front with __stdcall and cdecl ... every order (because I saw different orders and every worked) but same run time error 48.

#include <string>
#include <Windows.h>

#ifdef __cplusplus
    extern "C" {
#endif

Because there is link problems if is just declare it as a C++, so should be C to be properly linked to VB.exe (different compilers)

I define then some enums and structures, I think is fine, but may I should also export the struct if in the function call there is this struct as an argument?, in the previous version was not...but I created a function without arguments and does not work neither.

enum ERROR_DLL{ SUCCESS_CP_OK = 0,SUCCESS_CP_CANCELLED = 1}

struct SDllIdentity{
    LPCSTR szID;
    LPCSTR szDeviceID;
}

This is why I include windows.h because in the VS2012 this was working I thought it was failing because I was not using LPCSTR that is a char * type, but even if I change it to char * does not work.

    int __stdcall __declspec(dllexport) InitialiseTerminal(const SDllIdentity* pSDllIdentity, LPCSTR szAddress, int nPort);
//May the order is wrong, but as previously said I tried diferent combinations

    int __stdcall __declspec(dllexport) DisconnectTerminal(const SDllIdentity* pSDllIdentity);
    //ADDCALL int DLLTRY DisconnectTerminal(const SDllIdentity* pSDllIdentity);
    #ifdef __cplusplus
        }
    #endif

.cpp:

#include "dlltry.h"
//then I define some variables and a class, but I don't want to be exported
__stdcall int InitialiseTerminal(const SDllIdentity* pSDllIdentity, LPCSTR szAddress, int nPort) { return 0;}
__stdcall int /*ADDCALL*/ DisconnectTerminal(const SDllIdentity* pSDllIdentity) { return 0; }

I did not include all the functions, but all looks the same, I hope I am not forgeting a ";" :S, I looked in all this sites:

http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/ http://msdn.microsoft.com/en-us/library/z4zxe9k8.aspx

I tried to midify .def, create libdlltrx.a, all that I read, my only next solution would be to install VS2008, because I think was compile with that one ... but not sure, please read that I make it work before but because of incompatibilities I can not run it in others and I do not want to install any other software in others PCs.

回答1:

Woah, that's a lot of unneccessary work you did there. If you want to run a dll created with any kind of Visual Studio, you need to install the redistributable components of that Visual Studio version on the target system. Whatever problem you have with your "solution", get 10 steps back and fix your original problem by installing them.