我发现了一些类似的问题(如这个,那个或这个),但没有人帮我解决我的问题.我有一个*.so文件(来自gnss-sdr的核心),如下所示:
$nm libgnss_system_parameters_dyn.so | c++filt |grep Gps_Eph
Run Code Online (Sandbox Code Playgroud)
包含符号Gps_Ephemeris::Gps_Ephemeris()
,它应该是一个构造函数.
我写了一些最小的代码:
#include <iostream>
#include <core/system_parameters/gps_ephemeris.h>
int main(int argc,const char* argv[])
{
Gps_Ephemeris ge;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我编译的是:
g++ main.cpp -std=c++0x -I some_include_path -L some_lib_path -l gnss_system_parameters_dyn`
Run Code Online (Sandbox Code Playgroud)
然后链接器抱怨:
/tmp/ccHCvldG.o: In function `main':
main.cpp:(.text+0x33): undefined reference to `Gps_Ephemeris::Gps_Ephemeris()'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我也尝试过cmake,但它生成的行类似于它(它只是-rdynamic
在链接之前添加),它仍然生成完全相同的链接器错误.
请注意,库和我的最小代码都使用相同的编译器(g ++ - 5)进行编译,具有完全相同的标志和相同的c ++ 0x标准.
解决Maxim Egorushkin的答案:
nm --demangle --defined-only --extern-only libgnss_system_parameters.so |grep …
Run Code Online (Sandbox Code Playgroud) 我只是想知道为什么名称修改从未被C++标准标准化.显然,使用不同的名称修改算法会损害互操作性[1],我认为没有任何优势可以实现定义.
也就是说,与调用约定或基元大小相反,机器本身并不关心甚至不知道如何调用函数.那么为什么它没有标准化,为什么它仍然没有标准化?编译器在版本之间无论如何都改变了规则.
[1]所有出口功能的人都extern "C"
说话量大.
我正在尝试创建一个导出名为"GetName"的函数的DLL.我希望其他代码能够调用此函数,而无需知道损坏的函数名称.
我的头文件如下所示:
#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif
EXPORT TCHAR * CALLBACK GetName();
Run Code Online (Sandbox Code Playgroud)
我的代码看起来像这样:
#include <windows.h>
#include "PluginOne.h"
int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
return TRUE ;
}
EXPORT TCHAR * CALLBACK GetName()
{
return TEXT("Test Name");
}
Run Code Online (Sandbox Code Playgroud)
当我构建时,DLL仍然导出名为"_GetName @ 0"的函数.
我究竟做错了什么?
我正在尝试学习和理解C++中的名称修改.以下是一些问题:
(1)来自devx
当全局函数被重载时,为每个重载版本生成的受损名称是唯一的.名称修改也适用于变量.因此,局部变量和具有相同用户给定名称的全局变量仍然会获得明显的错位名称.
除了重载函数和同名全局变量和局部变量之外,还有其他使用名称修改的示例吗?
(2)来自维基
需要出现这样的情况:语言允许使用相同的标识符命名不同的实体,只要它们占用不同的命名空间(其中命名空间通常由模块,类或显式命名空间指令定义).
我不明白为什么名字改编仅适用于该情况下,当识别属于不同的命名空间,因为重载函数可以在同一个命名空间和相同名称的全局和局部变量,也可以在相同的空间.怎么理解这个?
具有相同名称但在不同范围内的变量是否也使用名称修改?
(3)C有名称错误吗?如果没有,当一些全局和局部变量具有相同名称时,它如何处理?C没有重载功能,对吧?
感谢致敬!
例如:
template <typename T>
struct foo
{
using bar = int;
};
// _Z3bazi
void baz(foo<int>::bar quux) {
}
template <typename T>
void baz(typename foo<T>::bar quux) {
}
// _Z3bazIiEvN3fooIT_E3barE
template void baz<int>(foo<int>::bar quux);
Run Code Online (Sandbox Code Playgroud)
为什么要baz<int>
提到破败的形式foo
呢?怎么没有_Z3bazIiEvi
?
这显然是C++ 17 std::default_order<T>
提案在水中死亡的原因.
而objdump
我的.o文件的显示,我对同一类两种不同的析构函数.为什么?
Disassembly of section .text._ZN1AD0Ev:
0000000000000000 <_ZN1AD0Ev>:
0: 53 push %rbx
1: be 00 00 00 00 mov $0x0,%esi
6: 48 89 fb mov %rdi,%rbx
9: 48 c7 07 00 00 00 00 movq $0x0,(%rdi)
10: ba 2c 00 00 00 mov $0x2c,%edx
15: bf 00 00 00 00 mov $0x0,%edi
1a: e8 00 00 00 00 callq 1f <_ZN1AD0Ev+0x1f>
1f: 48 89 df mov %rbx,%rdi
22: be 08 00 00 00 mov $0x8,%esi
27: 5b pop %rbx …
Run Code Online (Sandbox Code Playgroud) void outputString(const char *str) {
cout << "outputString(const char *str) : " << str << endl;
}
Run Code Online (Sandbox Code Playgroud)
原来是
Dump of assembler code for function _Z12outputStringPKc:
0x004013ee <_Z12outputStringPKc+0>: push ebp
0x004013ef <_Z12outputStringPKc+1>: mov ebp,esp
0x004013f1 <_Z12outputStringPKc+3>: sub esp,0x8
0x004013f4 <_Z12outputStringPKc+6>: mov DWORD PTR [esp+4],0x443000
0x004013fc <_Z12outputStringPKc+14>: mov DWORD PTR [esp],0x4463c0
0x00401403 <_Z12outputStringPKc+21>: call 0x43f6e8 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x00401408 <_Z12outputStringPKc+26>: mov edx,DWORD PTR [ebp+8]
0x0040140b <_Z12outputStringPKc+29>: mov DWORD PTR [esp+4],edx
0x0040140f <_Z12outputStringPKc+33>: mov DWORD PTR [esp],eax
0x00401412 <_Z12outputStringPKc+36>: call 0x43f6e8 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x00401417 <_Z12outputStringPKc+41>: mov …
Run Code Online (Sandbox Code Playgroud) class foo
{
public:
void say_type_name()
{
std::cout << typeid(this).name() << std::endl;
}
};
int main()
{
foo f;;
f.say_type_name();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在我的ubuntu机器上用g ++ 打印P3foo.我不知道它为什么打印P3foo而不仅仅是foo.如果我改变代码就好
std::cout << typeid(*this).name() << std::endl;
Run Code Online (Sandbox Code Playgroud)
它打印3foo.
有什么想法吗?
我有一个C++对象文件,其中包含一些C++模板函数的实例.有问题的目标文件为模板参数的几种不同组合实例化相同的功能.我正在尝试调试一个问题,并希望查看模板函数的特定实例化的反汇编(也就是说,我知道我想要检查的函数的模板参数).我通常会这样做objdump
来反汇编目标文件,但它(至少在默认情况下)不能解析C++函数名称.有没有办法做到这一点?目标文件是使用gcc 4.6.1创建的.
name-mangling ×10
c++ ×9
c ×2
g++ ×2
assembly ×1
c++17 ×1
compilation ×1
disassembly ×1
extern ×1
gcc ×1
gdb ×1
itanium-abi ×1
linker ×1
objdump ×1
templates ×1
typeid ×1