Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cygwin GCC linking with Visual Studio library

I've created a simple library (static 64bit - .lib) using Visual Studio 2012 Express. All this library has is one function:

int get_number()
{ 
    return 67; 
}

Let's say that the produced lib is called NumTestLib64.lib.

I'm trying to compile a simple program (Let's call it test.cpp) using Cygwin64 which will link NumTestLib64.lib and will print the result of get_number():

#include <stdio.h>   

int get_number();

int main()
{
    printf("get_number: %d\n", get_number());
    return 0;
}

Pretty simple right? Evidently not.
Compiling with g++ -o test test.cpp -L. -lTestLibStatic64 returns:

/tmp/ccT57qc6.o:test.cpp:(.text+0xe): undefined reference to `get_number()'
/tmp/ccT57qc6.o:test.cpp:(.text+0xe): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `get_number()'
collect2: error: ld returned 1 exit status

and, g++ -o test test.cpp TestLibStatic64.lib returns:

/tmp/ccMY8yNi.o:test.cpp:(.text+0xe): undefined reference to `get_number()'
/tmp/ccMY8yNi.o:test.cpp:(.text+0xe): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `get_number()'
collect2: error: ld returned 1 exit status

I'm looking for the brave ones who can provide instructions, both on the Visual Studio side and on the Cygwin command line side, as to how to get this thing done.

I've tried all the possible web pages, so probably links won't help, just exact instructions. I don't mind changing the library to DLL or perform any changes necessary, all code is mine, both in this simple example and in the actual application I'm developing.

Please help!

like image 789
madhat1 Avatar asked Oct 31 '22 21:10

madhat1


1 Answers

Found the answer! The key is creating both the *.dll and *.lib files. The *.lib is created when symbols are actually exported. Below is the header file of the created DLL (onlty worked when created DLL in Visual Studio, creating a static library doesn't work yet):

#ifdef TESTLIB_EXPORTS
#define TESTLIB_API __declspec(dllexport)
#else
#define TESTLIB_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C"
{
#endif

TESTLIB_API int get_num();

#ifdef __cplusplus
}
#endif

Of course, TESTLIB_EXPORTS is defined only in the DLL project. It's important that the main that links to this DLL will use this header, because of the __declspec(dllimport) part. Also, extern "C" is a must, as the commentators suggested, to avoid mangling. Also, I've been successful in linking on Cygwin32 and MinGW32, and not on Cygwin64.

like image 147
madhat1 Avatar answered Nov 15 '22 04:11

madhat1