#c #visual-studio-2012 #gcc #cygwin #static-libraries
#c #visual-studio-2012 #gcc #cygwin #статические библиотеки
Вопрос:
Я создал простую библиотеку (статическую 64-битную — .lib) с использованием Visual Studio 2012 Express. Все, что есть в этой библиотеке, — это одна функция:
int get_number()
{
return 67;
}
Допустим, вызывается созданная библиотека NumTestLib64.lib
.
Я пытаюсь скомпилировать простую программу (назовем ее test.cpp
), используя Cygwin64, которая свяжет NumTestLib64.lib
и выведет результат get_number()
:
#include <stdio.h>
int get_number();
int main()
{
printf("get_number: %dn", get_number());
return 0;
}
Довольно просто, не так ли? Очевидно, нет.
Компиляция с g -o test test.cpp -L. -lTestLibStatic64
возвратами:
/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
и g -o test test.cpp TestLibStatic64.lib
возвращает:
/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
Я ищу смелых, которые могут предоставить инструкции, как на стороне Visual Studio, так и на стороне командной строки Cygwin, о том, как это сделать.
Я перепробовал все возможные веб-страницы, поэтому, вероятно, ссылки не помогут, только точные инструкции. Я не против изменить библиотеку на DLL или выполнить какие-либо необходимые изменения, весь код принадлежит мне, как в этом простом примере, так и в реальном приложении, которое я разрабатываю.
Пожалуйста, помогите!
Комментарии:
1. Вы можете попробовать использовать
extern "C"
передget_number
2. Я также думаю, что проблема, с которой вы столкнулись, заключается в том, что VS2012 и GCC используют разные модели для искажения имен. ИМХО, единственный способ обойти это — определить все методы API как обычный c (используя
extern "C"
, как указано выше).3. Я пробовал. Добавлен внешний символ «C» к объявлению в коде библиотеки. Даже изменил весь проект на проект C (изменен с .cpp на .c). По-прежнему не работает. Я получаю ошибку «неопределенная ссылка на get_num ()».
Ответ №1:
Найден ответ! Ключом является создание файлов * .dll и * .lib. *.lib создается, когда символы фактически экспортируются. Ниже приведен файл заголовка созданной библиотеки DLL (работал только при создании DLL в Visual Studio, создание статической библиотеки пока не работает):
#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
Конечно, TESTLIB_EXPORTS
определяется только в проекте DLL.
Важно, чтобы основной, который ссылается на эту DLL, использовал этот заголовок из-за __declspec(dllimport)
части. Кроме того, extern "C"
необходимо, как предположили комментаторы, избегать искажений.
Кроме того, мне удалось выполнить связывание на Cygwin32 и MinGW32, а не на Cygwin64.