C++ 如何使用 g++ 正确链接到静态库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9078513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you properly link to a static library using g++
提问by DivXZero
Solution: Thanks to everyone who commented on this issue, but I resolved it on another forum, and figured I would post the answer here for anybody having the same issue.
So, I guess only dynamic libraries make use of __declspec(dllexport), so when you try to create a static library, the methods are exported (an the names need to be mangled to be c++ compatible), so when declaring extern "C" __declspec.... you end up with method names that aren't recognized when trying to link statically.
So, simple fix.....remove the __declspec
解决方案:感谢对此问题发表评论的每个人,但我在另一个论坛上解决了这个问题,并认为我会在此处为遇到相同问题的任何人发布答案。
所以,我猜只有动态库使用 __declspec(dllexport),所以当你尝试创建一个静态库时,方法被导出(名称需要被修改为与 C++ 兼容),所以在声明 extern "C" 时__declspec .... 尝试静态链接时,您最终会得到无法识别的方法名称。
所以,简单的修复.....删除 __declspec
I have 2 projects, one is a static library, the other is just a win32 application.
我有 2 个项目,一个是静态库,另一个只是一个 win32 应用程序。
I simply want to include the library I've created into my win32 application, however g++ keeps giving me this error:
我只是想将我创建的库包含到我的 win32 应用程序中,但是 g++ 一直给我这个错误:
../MyLib/TestClass.h:16: undefined reference to `imp__ZTV9TestClass'
../MyLib/TestClass.h:16: 未定义对 ` imp__ZTV9TestClass' 的引用
That is the error I get when trying to compile the application, even though that file is part of the library.
这是我在尝试编译应用程序时遇到的错误,即使该文件是库的一部分。
I have attempted to create the most simplified version of this project as possible in an attempt to find the error.
我试图尽可能地创建这个项目的最简化版本以试图找到错误。
Here are the source files for both projects:
以下是两个项目的源文件:
MyLib.h - This is the main include file for clients to reference functions in the library
MyLib.h - 这是客户端引用库中函数的主要包含文件
#ifndef MYLIB_H
#define MYLIB_H
#include "libexport.h"
#include "TestClass.h"
#endif /* MYLIB_H */
libexport.h - Pretty generic file to define import/export keywords
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
测试类.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
测试类.cpp
#define LIB
#include <stdio.h>
#include "TestClass.h"
void TestClass::TestFunc()
{
printf("This function was called from within the library.\n");
}
And lastly, the win32 application that implements the library:
最后,实现库的 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;
}
The library compiles with no errors, however, here is the output when compiling the main application:
库编译没有错误,但是,这是编译主应用程序时的输出:
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)
Most of the other posts I've seen regarding this topic say that the problem lies in the linking order, but even after adding -lmylib to the beginning of the compiler build line, the same errors persist:
我看过的大多数关于这个主题的其他帖子都说问题在于链接顺序,但即使在将 -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'
I really need help on this, I've built many dynamic libraries before using the above code, and it works with no problems, I can't understand why I'm having so much trouble building a simple static library. Any help is greatly appreciated.
我真的需要这方面的帮助,在使用上述代码之前我已经构建了许多动态库,并且它没有问题,我不明白为什么我在构建一个简单的静态库时遇到这么多麻烦。任何帮助是极大的赞赏。
采纳答案by DivXZero
Solution: Thanks to everyone who commented on this issue, but I resolved it on another forum, and figured out I would post the answer here for anybody having the same issue.
解决方案:感谢所有对此问题发表评论的人,但我在另一个论坛上解决了这个问题,并想我会在这里为遇到相同问题的任何人发布答案。
So, I guess only dynamic libraries make use of __declspec(dllexport)
, so when you try to create a static library, the methods are exported (an the names need to be mangled to be C++ compatible), so when declaring extern "C" __declspec....
you end up with method names that aren't recognized when trying to link statically.
所以,我猜只有动态库会使用__declspec(dllexport)
,所以当你尝试创建一个静态库时,方法被导出(名称需要被修改以与 C++ 兼容),所以当extern "C" __declspec....
你声明你最终得到的方法名称不是尝试静态链接时无法识别。
So, simple fix: remove the __declspec
所以,简单的修复:删除 __declspec
回答by TeaOverflow
-L/path/to/library/
and -lName
as g++ options worked for me. Do not specify the library name in the path/to/library
.
-L/path/to/library/
并且-lName
因为 g++ 选项对我有用。不要在path/to/library
.
回答by selalerer
Try putting -L and -l before main.o in the linking command line.
尝试在链接命令行中将 -L 和 -l 放在 main.o 之前。