Qt添加库连接,添加lib文件是没有问题,添加obj时出现文件格式不能被识别的错误。。。

jinxiang603 2016-08-15 09:29:12

按照上图在pro文件中添加连接的库文件,添加lib文件是没有问题,可以识别并使用其中的函数的。但是添加obj时,就出现文件格式不能被识别的错误。。。
尝试过改变写法:LIBS += -LC:/Users/jinxiang/Desktop/VG/ -lni4882就出现找不到这个文件了,如下图


已经尝试过很多次了,一直找不到解决的办法。。。请大家帮忙看看,还有什么是我没有考虑到的,难道Qt不能添加obj的库文件吗?在VS2010中都是可以直接添加附加依赖项的呀!谢谢
...全文
1106 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-08-15
  • 打赏
  • 举报
回复
Windows下先学会使用dumpbin查看obj
jinxiang603 2016-08-15
  • 打赏
  • 举报
回复
大概有点明白怎么回事,但是还是无从下手的感觉。 我用的Windows,不是Linux
赵4老师 2016-08-15
  • 打赏
  • 举报
回复
Linux下搜“Name Mangling in C++”
赵4老师 2016-08-15
  • 打赏
  • 举报
回复
C格式和CPP格式的obj是不同的。 dll 导出函数名的那些事 关键字: VC++  DLL 导出函数  经常使用VC6的Dependency查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系。 VC++支持两种语言:即C/C++,这也是造成DLL导出函数差异的根源 我们用VS2008新建个DLL工程,工程名为"TestDLL" 把默认的源文件后缀 .CPP改为.C(C文件) 输入测试代码如下: 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数,我们有以下几个方法: 1. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def),文件内容为: LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件:/DEF:"TestDll.Def" 2. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法,我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数: 第一种方法导出的函数为: MyFunction 第二种方法导出的函数为: _MyFunction@4 __stdcall会使导出函数名字前面加一个下划线,后面加一个@再加上参数的字节数,比如_MyFunction@4的参数(int iVariant)就是4个字节 __fastcall与 __stdcall类似,不过前面没有下划线,而是一个@,比如@MyFunction@4 __cdecl则是始函数名。 小结:如果要导出C文件中的函数,并且不让编译器改动函数名,用def文件导出函数。 下面我们来看一下C++文件 我们用VS2008新建个DLL工程,工程名为"TestDLL" 默认的源文件后缀为 .CPP (即C++文件)。 输入测试代码如下: 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数,我们有以下几个方法: 3. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def),文件内容为: LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件:/DEF:"TestDll.Def" 4. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法,我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数: 第一种方法导出的函数为: MyFunction 第二种方法导出的函数为: ?MyFunction@@YGHH@Z 可以看到 第二种方法得到的 导出函数名 并不是我们想要的,如果在exe中用显示方法(LoadLibrary、GetProcAddress)调用 MyFunction 肯定会失败。 但是用引入库(*.LIB)的方式调用,则编译器自动处理转换函数名,所以总是没有问题。 解决这个问题的方法是: 用VC 提供的预处理指示符 "#pragma" 来指定链接选项。 如下: #pragma comment(linker, "/EXPORT:MyFunction=?MyFunction@@YGHH@Z") 这时,就会发现导出的函数名字表中已经有了我们想要的MyFunction。但我们发现原来的那个 ?MyFunction@@YGHH@Z 函数还在,这时就可以把 __declspec() 修饰去掉,只需要 pragma 指令即可。 而且还可以使如下形式: #pragma comment(linker, "/EXPORT:MyFunction=_MyFunction@4,PRIVATE") PRIVATE 的作用与其在 def 文件中的作用一样。更多的#pragram请查看MSDN。 小结:如果要导出C++文件中的函数,并且不让编译器改动函数名,用def文件导出函数。 同时可以用#pragma指令(C 中也可以用)。 总结: C++编译器在生成DLL时,会对导出的函数进行名字改编,并且不同的编译器使用的改编规则不一样,因此改编后的名字也是不同的(一般涉及到C++ 中的重载等)。 如果利用不同编译器分别生成DLL和访问DLL的exe程序,后者在访问该DLL的导出函数时就会出现问题。如上例中函数MyFunction在C++编译器改编后的名字是?MyFunction@@YGHH@Z。我们希望编译后的名字不发生改变,这里有几种方法。 第一种方法是通过一个称为模块定义文件DEF来解决。 LIBRARY TestDll EXPORTS MyFunction LIBRARY 用来指定动态链接库内部名称。该名称与生成的动态链接库名一定要匹配,这句代码不是必须的。 EXPORTS说明了DLL将要导出的函数,以及为这些导出函数指定的符号名。 第二种是定义导出函数时加上限定符:extern "C" 如:#define DLLEXPORT_API extern "C" _declspec(dllexport) 但extern "C"只解决了C和C++语方之间调用的问题(extern "C" 是告诉编译器,让它按C的方式编译),它只能用于导出全局函数这种情况 而不能导出一个类的成员函数。 同时如果导出函数的调用约定发生改变,即使使用extern "C",编译后的函数名还是会发生改变。例如上面我们加入_stdcall关键字说明调用约定(标准调用约定,也就是WINAPI调用约定)。 #define DLLEXPORT_API extern "C" _declspec(dllexport) 01 DLLEXPORT_API int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 编译后函数名MyFunction改编成了_MyFunction@4 通过第一种方法模块定义文件的方式DLL编译后导出函数名不会发生改变。 DLL(动态库)导出函数名乱码含义 C++编译时函数名修饰约定规则: __stdcall调用约定: 1、以"?"标识函数名的开始,后跟函数名; 2、函数名后面以"@@YG"标识参数表的开始,后跟参数表; 3、参数表以代号表示: X--void D--char E--unsigned char F--short H--int I--unsigned int J--long K--unsigned long M--float N--double _N--bool .... PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个"0"代表一次重复; 4、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前; 5、参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束。 其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ",例如 int Test1(char *var1, unsigned long)-----"?Test1@@YGHPADK@Z" void Test2()-----"?Test2@@YGXXZ" __cdecl调用约定: 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YA"。 __fastcall调用约定: 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YI"。 如果要用DEF文件输出一个"C++"类,则把要输出的数据和成员的修饰名都写入.def模块定义文件 所以... 通过def文件来导出C++类是很麻烦的,并且这个修饰名是不可避免的
jinxiang603 2016-08-15
  • 打赏
  • 举报
回复

感觉能够识别的时候又会出现这样的问题,不知道是什么意思。
jinxiang603 2016-08-15
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
至少你要弄清楚你使用的obj是64位/32位,for Intel/AMD/...CPU,……的吧。
有两个obj,分别是32位和64位的。至于您说的后面的不是太懂。 之前用MFC的时候,直接在附加依赖项里面添加obj的路径就可以了的
赵4老师 2016-08-15
  • 打赏
  • 举报
回复
至少你要弄清楚你使用的obj是64位/32位,for Intel/AMD/...CPU,……的吧。
jinxiang603 2016-08-15
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
会用dumpbin或objdump查看obj的各项属性吗?
没有用过,不过搜了一下这个的意思,看这个要干什么呢?
赵4老师 2016-08-15
  • 打赏
  • 举报
回复
会用dumpbin或objdump查看obj的各项属性吗?
jinxiang603 2016-08-15
  • 打赏
  • 举报
回复
这个obj已经生成的好,我也不可以去重新生成的。现在只能看怎么去使用了....请老师指导啊
赵4老师 2016-08-15
  • 打赏
  • 举报
回复
dll 导出函数名的那些事 关键字: VC++  DLL 导出函数  经常使用VC6的Dependency查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系。 VC++支持两种语言:即C/C++,这也是造成DLL导出函数差异的根源 我们用VS2008新建个DLL工程,工程名为"TestDLL" 把默认的源文件后缀 .CPP改为.C(C文件) 输入测试代码如下: 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数,我们有以下几个方法: 1. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def),文件内容为: LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件:/DEF:"TestDll.Def" 2. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法,我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数: 第一种方法导出的函数为: MyFunction 第二种方法导出的函数为: _MyFunction@4 __stdcall会使导出函数名字前面加一个下划线,后面加一个@再加上参数的字节数,比如_MyFunction@4的参数(int iVariant)就是4个字节 __fastcall与 __stdcall类似,不过前面没有下划线,而是一个@,比如@MyFunction@4 __cdecl则是始函数名。 小结:如果要导出C文件中的函数,并且不让编译器改动函数名,用def文件导出函数。 下面我们来看一下C++文件 我们用VS2008新建个DLL工程,工程名为"TestDLL" 默认的源文件后缀为 .CPP (即C++文件)。 输入测试代码如下: 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数,我们有以下几个方法: 3. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def),文件内容为: LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件:/DEF:"TestDll.Def" 4. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法,我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数: 第一种方法导出的函数为: MyFunction 第二种方法导出的函数为: ?MyFunction@@YGHH@Z 可以看到 第二种方法得到的 导出函数名 并不是我们想要的,如果在exe中用显示方法(LoadLibrary、GetProcAddress)调用 MyFunction 肯定会失败。 但是用引入库(*.LIB)的方式调用,则编译器自动处理转换函数名,所以总是没有问题。 解决这个问题的方法是: 用VC 提供的预处理指示符 "#pragma" 来指定链接选项。 如下: #pragma comment(linker, "/EXPORT:MyFunction=?MyFunction@@YGHH@Z") 这时,就会发现导出的函数名字表中已经有了我们想要的MyFunction。但我们发现原来的那个 ?MyFunction@@YGHH@Z 函数还在,这时就可以把 __declspec() 修饰去掉,只需要 pragma 指令即可。 而且还可以使如下形式: #pragma comment(linker, "/EXPORT:MyFunction=_MyFunction@4,PRIVATE") PRIVATE 的作用与其在 def 文件中的作用一样。更多的#pragram请查看MSDN。 小结:如果要导出C++文件中的函数,并且不让编译器改动函数名,用def文件导出函数。 同时可以用#pragma指令(C 中也可以用)。 总结: C++编译器在生成DLL时,会对导出的函数进行名字改编,并且不同的编译器使用的改编规则不一样,因此改编后的名字也是不同的(一般涉及到C++ 中的重载等)。 如果利用不同编译器分别生成DLL和访问DLL的exe程序,后者在访问该DLL的导出函数时就会出现问题。如上例中函数MyFunction在C++编译器改编后的名字是?MyFunction@@YGHH@Z。我们希望编译后的名字不发生改变,这里有几种方法。 第一种方法是通过一个称为模块定义文件DEF来解决。 LIBRARY TestDll EXPORTS MyFunction LIBRARY 用来指定动态链接库内部名称。该名称与生成的动态链接库名一定要匹配,这句代码不是必须的。 EXPORTS说明了DLL将要导出的函数,以及为这些导出函数指定的符号名。 第二种是定义导出函数时加上限定符:extern "C" 如:#define DLLEXPORT_API extern "C" _declspec(dllexport) 但extern "C"只解决了C和C++语方之间调用的问题(extern "C" 是告诉编译器,让它按C的方式编译),它只能用于导出全局函数这种情况 而不能导出一个类的成员函数。 同时如果导出函数的调用约定发生改变,即使使用extern "C",编译后的函数名还是会发生改变。例如上面我们加入_stdcall关键字说明调用约定(标准调用约定,也就是WINAPI调用约定)。 #define DLLEXPORT_API extern "C" _declspec(dllexport) 01 DLLEXPORT_API int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 编译后函数名MyFunction改编成了_MyFunction@4 通过第一种方法模块定义文件的方式DLL编译后导出函数名不会发生改变。 DLL(动态库)导出函数名乱码含义 C++编译时函数名修饰约定规则: __stdcall调用约定: 1、以"?"标识函数名的开始,后跟函数名; 2、函数名后面以"@@YG"标识参数表的开始,后跟参数表; 3、参数表以代号表示: X--void D--char E--unsigned char F--short H--int I--unsigned int J--long K--unsigned long M--float N--double _N--bool .... PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个"0"代表一次重复; 4、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前; 5、参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束。 其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ",例如 int Test1(char *var1, unsigned long)-----"?Test1@@YGHPADK@Z" void Test2()-----"?Test2@@YGXXZ" __cdecl调用约定: 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YA"。 __fastcall调用约定: 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YI"。 如果要用DEF文件输出一个"C++"类,则把要输出的数据和成员的修饰名都写入.def模块定义文件 所以... 通过def文件来导出C++类是很麻烦的,并且这个修饰名是不可避免的
jinxiang603 2016-08-15
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
Windows下先学会使用dumpbin查看obj


按照网上的查看它里面包含的函数,然后生成了一个txt文件,里面大概是这样,函数名称是变的不一样了
网管教程 从入门到精通软件篇 ★一。★详细的xp修复控制台命令和用法!!! 放入xp(2000)的光盘,安装候选R,修复! Windows XP(包括 Windows 2000)的控制台命令是在系统出现一些意外情况下的一种非常有效的诊断和测试以及恢复系统功能的工具。小编的确一直都想把这方面的命令做个总结,这次辛苦老范给我们整理了这份实用的秘笈。   Bootcfg   bootcfg 命令启动配置和故障恢复(对于大多数计算机,即 boot.ini 文件)。   含有下列参数的 bootcfg 命令仅在使用故障恢复控制台才可用。可在命令提示符下使用带有不同参数的 bootcfg 命令。   用法:   bootcfg /default  设置默认引导项。   bootcfg /add    向引导列表中添加 Windows 安装。   bootcfg /rebuild  重复全部 Windows 安装过程并允许用户选择要添加的内容。   注意:使用 bootcfg /rebuild 之前,应先通过 bootcfg /copy 命令备份 boot.ini 文件。   bootcfg /scan    扫描用于 Windows 安装的所有磁盘并显示结果。   注意:这些结果被静态存储,并用于本次会话。如果在本次会话期间磁盘配置发生变化,为获得更新的扫描,必须先重新启动计算机,然后再次扫描磁盘。   bootcfg /list   列出引导列表中已有的条目。   bootcfg /disableredirect 在启动引导程序中禁用重定向。   bootcfg /redirect [ PortBaudRrate] |[ useBiosSettings]   在启动引导程序中通过指定配置启用重定向。   范例: bootcfg /redirect com1 115200 bootcfg /redirect useBiosSettings   hkdsk   创建并显示磁盘的状态报告。Chkdsk 命令还可列出并纠正磁盘上的错误。   含有下列参数的 chkdsk 命令仅在使用故障恢复控制台才可用。可在命令提示符下使用带有不同参数的 chkdsk 命令。   vol [drive:] [ chkdsk [drive:] [/p] [/r]   参数  无   如果不带任何参数,chkdsk 将显示当前驱动器中的磁盘状态。 drive: 指定要 chkdsk 检查的驱动器。 /p   即使驱动器不在 chkdsk 的检查范围内,也执行彻底检查。该参数不对驱动器做任何更改。 /r   找到坏扇区并恢复可读取的信息。隐含着 /p 参数。   注意 Chkdsk 命令需要 Autochk.exe 文件。如果不能在启动目录(默认为 %systemroot%System32)中找到该文件,将试着在 Windows 安装 CD 中找到它。如果有多引导系统的计算机,必须保证是在包含 Windows 的驱动器上使用该命令。 Diskpart   创建和删除硬盘驱动器上的分区。diskpart 命令仅在使用故障恢复控制台才可用。   diskpart [ /add |/delete] [device_name |drive_name |partition_name] [size]   参数 无   如果不带任何参数,diskpart 命令将启动 diskpart 的 Windows 字符模式版本。   /add   创建新的分区。   /delete   删除现有分区。   device_name   要创建或删除分区的设备。设备名称可从 map 命令的输出获得。例如,设备名称:   DeviceHardDisk0   drive_name   以驱动器号表示的待删除分区。仅与 /delete 同使用。以下是驱动器名称的范例:   D:   partition_name   以分区名称表示的待删除分区。可代替 drive_name 使用。仅与 /delete 同使用。以下是分区名称的范例:   DeviceHardDisk0Partition1    大小   要创建的分区大小,以兆字节 (MB)表示。仅与 /add 同使用。   范例   下例将删除分区: diskpart /delete Device HardDisk0 Partition3 diskpart /delete F:   下例将在硬盘上添加一个 20 MB 的分区:   diskpart /add Device HardDisk0 20   Fixboot

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧