How to use libraries compiled with MingW in MSVC?
Asked Answered
C

4

24

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 about 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.

Crosspatch answered 27/3, 2010 at 15:11 Comment(3)
Couldn't you compile everything on MSVC?Suprematism
"Either .a and .lib are just AR archives of .o or .obj files" Are you sure that msvc's static .lib files are just like .a "ar" archives?Rhabdomancy
It looks like this question (and answers) are specific to C rather than C++ ... can you confirm?Abroms
I
17

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@.

Infinitesimal answered 27/3, 2010 at 16:25 Comment(3)
This is certainly a likely solution, but if true I'm surprised that SSL doesn't do it itself - maybe the author hates C++ :-)Karakul
@Karakul OpenSSL is a C library, and extern "C" is a C++ syntax.Skantze
He says his project is written in C. Is it guaranteed that libraries compiled with one will work with the other? For example, how about Static Libraries?Septimal
M
13

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.

Melanie answered 13/6, 2010 at 5:11 Comment(1)
The reason the .dll should be in the same directory as the .def is because the .def is just meta-information used for converting. The question that remains is: does converting with lib.exe also work if the library does not have a C style interface? The fact that this answer mentions a runtime error implies the utility is rather useless...Zenithal
K
12

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.

Karakul answered 27/3, 2010 at 15:19 Comment(5)
So what should I do in order to link the MingW compiled lib with MSVC compiled executable successfully?Crosspatch
The application Im linking the libraries to is written in C++, the libraries being linked are C (its openssl, zlib and xerces)Crosspatch
@Crosspatch OK, please post a few (three or four) of the linker errors you are getting by editing them into your question. It's still not clear if you have a mangling problem, or something else.Karakul
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 namesCrosspatch
@Crosspatch Could you do as I asked, and post all the errors by editing your question, not by posting a comment?Karakul
R
8

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:--

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

Roice answered 14/7, 2020 at 13:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.