Как правильно связать статическую библиотеку с помощью g ++ - PullRequest
4 голосов
/ 31 января 2012

Решение: Спасибо всем, кто прокомментировал эту проблему, но я решил ее на другом форуме и подумал, что я опубликую ответ здесь для тех, у кого такая же проблема.

Итак, я думаю,только динамические библиотеки используют __declspec (dllexport), поэтому при попытке создать статическую библиотеку методы экспортируются (имена должны быть искажены, чтобы быть совместимыми с ++), поэтому при объявлении extern "C" __declspec ...... вы получите имена методов, которые не распознаются при попытке статически связать.

Итак, простое исправление ..... удалите __declspec

У меня есть 2 проекта,одна - статическая библиотека, другая - просто приложение win32.

Я просто хочу включить созданную мной библиотеку в мое приложение win32, однако g ++ продолжает выдавать мне эту ошибку:

../MyLib/TestClass.h:16: неопределенная ссылка на ` imp __ ZTV9TestClass '

Это ошибка, возникающая при попытке скомпилировать приложение, даже если этот файл является частьюбиблиотеки.

Я попытался создать максимально упрощенную версию этого проекта, пытаясь найти ошибку.

Вот исходные файлы для обоих проектов:

MyLib.h - это основной включаемый файл для клиентов для ссылки на функции в библиотеке

#ifndef MYLIB_H
#define MYLIB_H

#include "libexport.h"
#include "TestClass.h"

#endif  /* MYLIB_H */

libexport.h - довольно общий файл для определения ключевых слов импорта / экспорта

#ifndef LIBEXPORT_H
#define LIBEXPORT_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef LIB
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif

#ifdef __cplusplus
}
#endif

#endif  /* LIBEXPORT_H */

TestClass.h

#ifndef TESTCLASS_H
#define TESTCLASS_H

#include "libexport.h"

class DLL_EXPORT TestClass
{
public:
    TestClass() {};
    virtual ~TestClass() {};

    void TestFunc();
};

#endif  /* TESTCLASS_H */

TestClass.cpp

#define LIB

#include <stdio.h>
#include "TestClass.h"

void TestClass::TestFunc()
{
    printf("This function was called from within the library.\n");
}

И, наконец, приложение win32, которое реализует библиотеку:

Main.cpp

#include <windows.h>
#include "../MyLib/MyLib.h"

#pragma comment(lib, "libmylib.a")

int __stdcall WinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPSTR lpCmdLine,
                      int nCmdShow)
{

    TestClass *myClass = new TestClass();

    delete myClass;
    myClass = 0;

    return 0;
}

Библиотека компилируется без ошибок, однако, вот вывод при компиляции основного приложения:

g++.exe    -c -g -MMD -MP -MF build/Debug/MinGW-Windows/main.o.d -o build/Debug/MinGW-Windows/main.o main.cpp
mkdir -p dist/Debug/MinGW-Windows
g++.exe     -mwindows -o dist/Debug/MinGW-Windows/testclient build/Debug/MinGW-Windows/main.o -L../MyLib/dist/Debug/MinGW-Windows -lmylib 
build/Debug/MinGW-Windows/main.o: In function `TestClass':
C:\Users\Nick\Documents\NetBeansProjects\TestClient/../MyLib/TestClass.h:16: undefined reference to `_imp___ZTV9TestClass'
make[2]: Leaving directory `/c/Users/Nick/Documents/NetBeansProjects/TestClient'
build/Debug/MinGW-Windows/main.o: In function `~TestClass':
make[1]: Leaving directory `/c/Users/Nick/Documents/NetBeansProjects/TestClient'
C:\Users\Nick\Documents\NetBeansProjects\TestClient/../MyLib/TestClass.h:17: undefined reference to `_imp___ZTV9TestClass'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/MinGW-Windows/testclient.exe] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2


BUILD FAILED (exit value 2, total time: 1s)

Большинство других постов, которые я видел по этой теме, говорят, что проблема заключается вв порядке компоновки, но даже после добавления -lmylib в начало строки сборки компилятора сохраняются те же ошибки:

g++.exe -lmylib -mwindows -o dist/Debug/MinGW-Windows/testclient build/Debug/MinGW-Windows/main.o -L../MyLib/dist/Debug/MinGW-Windows -lmylib 
build/Debug/MinGW-Windows/main.o: In function `TestClass':
C:\Users\Nick\Documents\NetBeansProjects\TestClient/../MyLib/TestClass.h:16: undefined reference to `_imp___ZTV9TestClass'

Мне действительно нужна помощь по этому вопросу, перед использованием я собрал много динамических библиотекаЯ не могу понять, почему у меня так много проблем с созданием простой статической библиотеки.Любая помощь с благодарностью.

Ответы [ 3 ]

2 голосов
/ 31 января 2012

-L/path/to/library/ и -lName как опции g ++ работали для меня.Не указывайте имя библиотеки в path/to/library.

1 голос
/ 31 января 2012

Решение: Спасибо всем, кто прокомментировал эту проблему, но я решил ее на другом форуме и выяснил, что оставлю здесь ответ для всех, у кого возникла такая же проблема.

Итак, я предполагаю, что только динамические библиотеки используют __declspec(dllexport), поэтому при попытке создать статическую библиотеку методы экспортируются (имена должны быть искажены, чтобы быть совместимыми с C ++), поэтому при объявлении extern "C" __declspec.... вы получите имена методов, которые не распознаются при попытке статической ссылки.

Итак, простое исправление: удалите __declspec

1 голос
/ 31 января 2012

Попробуйте поместить -L и -l перед main.o в командной строке связывания.

...