开发者

How to use libraries compiled with MingW in MSVC?

I have compiled several libraries with MingW/MSYS... the generated static libraries are always .a files. When I try to link the library with a MSVC project, Visual Studio throws 'unresolved external symbols' ... It means that the .a static library is incompatible with MS C++ Linker. I presume it has to be converted to a MSVC compatible .lib file.

Either .a and .lib are just AR archives of .o or .obj files, so is there any way how to use MingW compiled libs in a MSVC project? Or do I have to compile/link everything just in one compiler/linker - MSVC only/MingW only? The MingW compiler is said to be compatible with MSVC.

I read a few threads abo开发者_运维技巧ut this topic, but they mostly say that renaming the file to .lib should do the work, but it unfortunately doesn't work for me.

The libraries Im trying to link are written in C.

MSVC Linker throws errors like:

error LNK2019: unresolved external symbol "int __cdecl openssl_call(struct ssl_State *,int,int,int)" (?openssl_call@@YAHPAUssl_State@@HHH@Z) referenced in function _main MyAPP.obj

... and 4 more same errors referring to other functions called from my app.

Thanks for any advice.


Based on this error you put in a comment:

error LNK2019: unresolved external symbol "int __cdecl openssl_call(struct ssl_State *,int,int,int)" (?openssl_call@@YAHPAUssl_State@@HHH@Z) referenced in function _main MyAPP.obj all other 4 errors are same only with other functions names

Try putting extern "C" around your include files for openssl. For example:

extern "C" {
include "openssl.h"
}

using extern "C" will instruct the compiler that the functions are using C linkage, not C++, which will stop it from performing name mangling on the functions. So it will look for the function openssl_call in the library rather than ?openssl_call@@YAHPAUssl_State@@HHH@.


The libraries are compatible, but only if you supply a C interface. MSVC and g++ use different name-mangling schemes, so you cannot easily link C++ code created with one with code created by the other.


I encounted the same situations that use mingw-compiled dll in MSVC. I use following tools to make it work:
1) use gcc like that:

gcc -shared -o your_dll.dll your_dll_src.c -Wl,--output-def,your_dll.def

The bolds specify that gcc will generate a *def file that scripts your exported items.Then you need to use lib.exe, which distributed with MSVC, example like this:

lib /def:your_dll.def

Then, there will be a your_dll.lib file, comes from lib.exe.(Assume that you_dll.dll located in the same directory as your_dll.def).

currently, I can use the *.lib in my MSVC project and link the dll correctly, but I got the runtime error. Anyway, such works make your linkage workable.


Introduction

Object files and static libraries created with different compilers, or even with significantly different releases of the same compiler, often cannot be linked together. This issue is not specific to MinGW: many other compilers are mutually incompatible. Build everything from source with the same version of the same compiler if you can.

Dll's are slightly different. Sometimes you can link a DLL built with one compiler to an application compiled with another. This works well if the DLL is written in C, even if the application is written in C++. For example, MinGW C++ programs commonly link to the C runtime library provided with Windows. DLLs that are written in C++ work too, as long as you communicate with them only through a C interface declared with extern "C". If you do otherwise, you will probably get linker errors because different compilers mangle C++ names differently.

Why Different Compilers may not Interoperate

Sometimes people wonder why compiler writers don't just use the same name-mangling scheme. That might make linking succeed, but would most likely give you a program that crashes when you call into the DLL. Real link compatibility requires a common Application Binary Interface, and name-mangling is just one consideration among many. Here's a partial list:--

  • http://ou800doc.caldera.com/SDK_porting/binary_cplusplus_compat.html
  • One compiler offers 3200 different ABIs according to this page: http://www.boost.org/libs/config/config.htm#source
  • According to Stroustrup (ARM, 7.2.1c, page 122):

If two C++ implementations for the same system use different calling sequences, or in other ways are not link compatible, it would be unwise to use identical encodings of type signatures.

Implementors have traditionally used deliberately different name-mangling schemes, figuring it's better to 'just say no' at link time than to make some simple code work and let the issues emerge at run time.

Even though GNU g++ can link MSVC C++ libraries now, and can produce MSVC++ compatible libraries/DLLs, this does not mean that they will be able to work at run-time due to the dynamic nature of C++. Some possible reasons for this are:--

  • The simple name mangling issue which it may be possible to circumvent with an explicit .def file.
  • Different structure alignment issues which need the correct compiler options (-mms-bitfields, ...).
  • A fundamental conflict of underlying exception and memory models:--
  1. A new/delete or malloc/free in a MSVC DLL will not co-operate with a Cygwin newlib new/delete or malloc/free. One cannot free space which was allocated in a function using a different new/malloc at all.
  2. An exception raised by an MSVC DLL will not be caught by a Cygwin executable, and vice versa.
  3. The slow GNU SJLJ exception model, (used in GCC-3.x and earlier), is compatible with the MSVC++ model, but the new DWARF2 model, (which will be used by GCC-4.x), will be incompatible.

Reference: http://www.mingw.org/wiki/Interoperability_of_Libraries_Created_by_Different_Compiler_Brands

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜