在mingw中使用msvc lib
我有一个硬件(X射线传感器),它有开发工具。 但afaiu这些都建于msvc。 所以我有一个.lib文件和.dll文件。 如果我将这个lib文件包含到我的项目中(我正在使用qt),并将dll文件放到exe文件夹中并使用MSVC-Release选项进行编译。 但是当我尝试使用mingw-Release选项进行编译时。 它失败。
未定义的引用'imp__ZN6IDcDrv6CreateEPKci'
未定义的引用'imp__ZN6IDcDrv14GetDeviceCountEv'
你能指出一些出路,以便我可以使用这些库。 和使用mingw编译器的dll文件
ps:我试过并且失败了impdef dclibsn.dll> dclib.def
dlltool -dllname dclibsn.dll --def dclib.def --output-lib libdclibsn.a
这就是我的def文件的样子
LIBRARY "dclibsn.dll"
EXPORTS
??0DcDrv@@QAE@ABV0@@Z
??0DcDrv@@QAE@V?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@@Z
??0IDcDrv@@QAE@ABV0@@Z
??0IDcDrv@@QAE@XZ
??1DcDrv@@QAE@XZ
??4DcDrv@@QAEAAV0@ABV0@@Z
??4IDcDrv@@QAEAAV0@ABV0@@Z
?CaptureImage@DcDrv@@AAE_NHHHK_NHH@Z
?CloseUsbDevice@DcDrv@@AAE_NXZ
?ColumnDefectComp@DcDrv@@AAEGPBGH@Z
?CompensationImage@DcDrv@@AAEXPAGQAEHH@Z
?Create@IDcDrv@@SAPAVDcDrv@@PBDH@Z
注意这个文件中的最后一个条目(Create)。我正试图在程序中调用它,并且我得到了
(.text+0x1ad): undefined reference to `_imp___ZN6IDcDrv6CreateEPKci'
如果我更换该行?Create @ IDcDrv @@ SAPAVDcDrv @@ PBDH @ Z
它会编译imp__ZN6IDcDrv6CreateEPKci,但会给出错误。
The procedure entry point _ZN6IDcDrv6CreateEPKci could not be located in the dynamic link library dclibsn.DLL.
看到这个:如何在MSVC中使用MingW编译的库?
我的意思是围绕#包含extern“C”块。 因为使用extern“C”将指示编译器该函数正在使用C链接,而不是C ++,这将阻止它对函数执行名称修改。
我认为名称混乱导致联系问题。 不知道这将有助于自动使用DLL或不。 希望它会。 因为我需要在MSVC 2005中编写一个基于CUDA的dll,并在mingw中使用它。
希望这个帮助。 : - ?
我当然不是这方面的专家,但我一直认为使用mingw构建的项目无法使用msvc项目中的任何dll或libs,因为它们是使用不同的编译器构建的。
这里有一个简单的问题:对于MS编译器和GCC,name mangling scheme,即从可能重载名称的C ++函数到仅通过名称标识函数的字符串的映射是不同的。 因此,函数名称是不同的,MingW搜索自己的错位名称格式( _ZN6IDcDrv6CreateEPKci
),并找不到微软错位的名称( ?Create@IDcDrv@@SAPAVDcDrv@@PBDH@Z
)。
现在,如果这两个库真正使用C ++特性,那就更好了。 假设你将C ++字符串从库中传递到你的程序中,并且返回 - 绝对不能保证字符串的MS实现与GNU实现是二进制兼容的,所以你最终可能会遇到令人讨厌的错误。
但是,如果这些函数的接口是C兼容的(可以用POD术语表示),则可以在extern "C"
块中声明这些函数,从而禁用名称修改。 看来你正在构建的lib的开发者没有这样做。 如果这是不必要的(对不起,我不能将MSVC名称去除为函数签名,所以真的不能告诉),您应该向库提交一个错误并让它们声明接口或尽可能使用extern "C"
声明大部分extern "C"
。 如果这是不可能的,在MSVC中编写一个包装函数,调用它们的函数并在extern "C"
声明它自己的函数。
下一篇: Is it safe to return a struct from an stdcall dll function?