从Qt应用程序链接到c++静态库
Linking to a C++ Static Library from a Qt Application
我正在尝试链接一个非qt静态库,到一个基于qt的应用程序(它是一个Visual Studio项目)。
问题是静态库有一些api,这些api将指向TCHAR字符串的指针作为输入之一。当我尝试构建项目时,我得到一个链接错误,抱怨TCHAR。
头
class Test
{
public:
static bool TestFunc( TCHAR *empty );
};
来源bool Test::TestFunc( TCHAR *empty )
{
return true;
}
错误:error LNK2019: unresolved external symbol "public: static bool __cdecl Test::TestFunc(unsigned short *)" (?TestFunc@Test@@SA_NPAG@Z) referenced in function "public: __thiscall TestApp::TestApp(class QWidget *,class QFlags<enum Qt::WindowType>)" (??0TestApp@@QAE@PAVQWidget@@V?$QFlags@W4WindowType@Qt@@@@@Z)
有趣的是,如果我在头文件中有函数实现,它工作得很好。或者,如果我将TCHAR更改为常规字符,并保持声明/定义分开,它也可以工作(使用wchar_t直接失败并产生相同的链接错误)。
有谁知道是什么导致了这个问题,以及如何解决它?
提前感谢,
静态库是用什么编译的?Visual studio ?什么版本?
我将尽力解释你所遇到的问题。
首先,当你把函数体放在头文件中,它工作的原因是,这实际上会导致你的应用程序重新编译函数体。链接器实际上不再需要解析来自静态库的任何符号。因此,链接器问题就解决了。
问题是,当编译静态库时,它导出的函数Test::TestFunc
被编译器弄乱了(它实际上是根据一些内部模式重命名它)。函数名混淆是编译器为简化链接器的符号解析所做的工作。在c++标准中没有指定函数名的修改方式。因此,不同的编译器,打开不同的设置,会以不同的方式处理函数名。
当您尝试构建链接此库的应用程序时,Visual Studio现在破坏了称为的函数(可能在main()
中)。如果定义函数的静态库的名称混淆与调用函数的名称混淆不匹配,那么就会得到收到的错误。也就是说,链接器将在静态库中查找函数X
,而它所能找到的只是函数Y
。
现在,正如其他海报所指出的,名称混乱也取决于函数作为输入的参数。如果两个地方(定义和用法)的参数类型不同,编译器将以不同的方式处理函数名。因此,链接器将再次无法解析匹配。
底线是,在符号存在的两个地方(库和应用程序),符号必须以相同的方式修改。要做到这一点,最好的方法是使用完全相同的编译器,具有完全相同的设置。当然,另一种可能性是该符号实际上并不存在于您所链接的静态库中!
确保两个项目的编译器设置相同。特别注意"Character Set"属性,确保它们都是Unicode。这将改变TCHAR
宏的定义。
默认情况下,VS编译时启用"将wchar_t视为内置类型" (/Zc:wchar_t
)。Qt编译时禁用该选项(/Zc:wchar_t-
)。如果在VS中禁用"将wchar_t视为内置类型"(在配置属性> C/c++>语言下),在构建静态库之前,是否可以修复它?
TCHAR是char或wchar(即utf16),这取决于应用程序的构建方式。
编辑:如果你想混合Qt的字符串类型与TCHAR
只需将QString转换为local8bit或utf16(),然后将结果强制转换为TCHAR*
和从TCHAR转换回QString
QString toQString(const char *str) { return QString::fromLocal8Bit(str); }
QString toQString(const wchar_t *str) { return QString::fromWCharArray(str); }
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- #为""定义宏;静态";针对不同的上下文
- cmake如何在fedora工作站中找到boost静态库包
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- cmake在我的项目中所需的所有静态库都不成功
- C++从另一个类访问公共静态向量的正确方法是什么
- 基于boost的程序的静态链接——zlib问题
- 在静态库中嵌入类方法
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 如何在C++中获得"静态纯虚拟"功能?
- 私有类型的静态常量成员
- 使用gcc从静态链接的文件中查找可选符号
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 如何在C++中使用非静态成员函数作为回调函数
- 将静态库链接到不带-fPIC的共享库中
- 静态结构和一个定义规则
- 为什么虚函数不能是静态的和全局的?
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身