【问题标题】:How do you properly link to a static library using g++如何使用 g++ 正确链接到静态库
【发布时间】:2012-02-23 02:40:24
【问题描述】:

解决方案: 感谢所有对此问题发表评论的人,但我在另一个论坛上解决了它,并认为我会在这里为遇到相同问题的任何人发布答案。

所以,我猜只有动态库使用 __declspec(dllexport),所以当您尝试创建静态库时,方法会被导出(名称需要被修改为与 c++ 兼容),所以在声明 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'

我真的需要帮助,在使用上述代码之前,我已经构建了许多动态库,并且它没有问题,我不明白为什么我在构建一个简单的静态库时遇到这么多麻烦。非常感谢任何帮助。

【问题讨论】:

  • 这是一个静态库,所以请尝试使用libmylib.a(没有-l)而不是-lmylib。您可能必须指定完整路径:build/Debug/libmylib.a 或其他。
  • 看起来会产生同样的结果:g++.exe -mwindows ../MyLib/dist/Debug/MinGW-Windows/libmylib.a -o dist/Debug/MinGW-Windows/testclient build /Debug/MinGW-Windows/main.o -L../MyLib/dist/Debug/MinGW-Windows -lmylib make[2]:离开目录/c/Users/Nick/Documents/NetBeansProjects/TestClient' make[1]: Leaving directory /c/Users/Nick/Documents/NetBeansProjects/TestClient' build /Debug/MinGW-Windows/main.o:在函数TestClass': C:\Users\Nick\Documents\NetBeansProjects\TestClient/../MyLib/TestClass.h:16: undefined reference to _imp___ZTV9TestClass'
  • 链接对象和ar档案的顺序也很重要
  • 不,最后是,我只是说我一开始就试过了,没有新的结果,如果你看看提供的信息会有所帮助。
  • ../MyLib/dist/Debug/MinGW-Windows/libmylib.a放在build/Debug/MinGW-Windows/main.o.之后

标签: c++ static linker g++


【解决方案1】:

-L/path/to/library/-lName 作为 g++ 选项对我有用。不要在 path/to/library 中指定库名称。

【讨论】:

  • 这正是我在给定示例中指定它的方式...“-L../MyLib/dist/Debug/MinGW-Windows -lmylib”但它仍然给出未定义的参考错误,这就是为什么我很困惑
  • 哦,对不起,一定错过了。 mylib 是否命名为 libmylib.a ?因为这就是 -l 选项所假定的。
【解决方案2】:

解决方案:感谢所有对此问题发表评论的人,但我在另一个论坛上解决了这个问题,并想出我会在这里为遇到相同问题的任何人发布答案。

所以,我猜只有动态库使用__declspec(dllexport),所以当您尝试创建静态库时,方法会被导出(名称需要被破坏以与 C++ 兼容),所以在声明 @987654322 时@您最终会得到在尝试静态链接时无法识别的方法名称。

所以,简单的修复:删除__declspec

【讨论】:

    【解决方案3】:

    尝试在链接命令行中将 -L 和 -l 放在 main.o 之前。

    【讨论】:

    • 没有区别,仍然得到相同的未定义引用错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多