gcc/Linux 使用的 C++ ABI/重整方案称为Itanium C++ ABI。Mangling 是第 5.1 节。
除了这个之外,还有多少其他常用的 C++ ABI 和重整方案?他们叫什么?
(例如,我假设 MSVC 和 Windows 有自己的一个?它叫什么?它在某处有记录吗?)
我有一个用C++编写的DLL,我想压缩一些导出方法的名称.这些方法是全局的,不是任何类的成员.有没有办法实现这个目标?
顺便说一句:我正在使用VS2008.
我正在尝试编译一个使用JNI的Java库.当我启动程序时,我看到一个带有UnsatisfiedLinkError的崩溃,它表示在DLL中找不到特定的方法.
仔细观察后,我发现用于编译和链接的g ++通过在方法名称中添加诸如"@ 8"或"@ 16"的后缀来破坏我的方法名称.有没有人知道正确的编译器选项来禁用名称修改?提前致谢!
编辑:我通过Eclipse + CDT插件使用MinGW.
嗨,我需要从c ++应用程序本身确定一个函数的错位名称.__FUNCDNAME__在g ++中有没有与宏相同的东西?
我有一个.lib文件,我没有源代码.
我需要一个导出的函数,但是我用C编写,函数是C++名称错误的.我不能写extern "C",因为我没有源代码.
如何在没有源代码和切换到C++的情况下链接损坏的函数?
是否可以从C代码中调用C++ DLL中的函数?该函数未声明extern "C".一个丑陋的平台依赖黑客,只适用于Visual Studio是好的.
调用约定不应该是一个主要问题,但我如何处理名称修改.例如,对于Visual Studio,带签名的C++函数具有void f()错位名称?f@@YAXXZ,并且不是合法的C标识符.
(你不需要告诉我,我应该将C++函数声明为extern "C".我已经知道了.但是我遇到了无法更改C++代码的情况.)
源代码(在问题的最后)将引发我认为是Solaris Studio上的错误错误(而不是其他编译器).
为清楚起见,使用新行重新格式化了错误消息:
"overload.cpp", line 44: Error:
runGenEntries<std::vector<int>>(const GenEntryRuleDriven<int>&, const std::vector<int>&)
and
runGenEntries<std::vector<int>>(const GenEntryRulesDriven<int>&, const std::vector<int>&)
have same extern name
"__1cNrunGenEntries4nDstdGvector4Cin0AJallocator4Ci_____6FrkTArk1_v_".
1 Error(s) detected.
Run Code Online (Sandbox Code Playgroud)
注意两个函数runGenEntries的第一个参数如何只有一个字符(规则末尾的's')
当第一个参数是类型时,似乎会发生这种情况:
const typename GenEntryRulesDrivenType<typename InputsType::value_type>::type
Run Code Online (Sandbox Code Playgroud)
并且当第一个参数而不是类型时不会发生:
const typename GenEntryRulesDriven<typename InputsType::value_type>
Run Code Online (Sandbox Code Playgroud)
最终解决了相同的类型!
这是仅在Solaris上实现的一些模糊的C++规则的结果吗?或者,当它破坏符号时,这是一个Solaris Studio错误吗?
以下源代码可以在任何编译器上编译.
定义将激活引发错误的代码,或者激活应该产生相同结果的代码(但这次没有错误):
#include <iostream>
#include <vector>
template<typename T>
struct GenEntryRulesDriven
{
void foo() const
{
}
};
template<typename T>
struct GenEntryRuleDriven
{
void bar() const
{
}
std::string toto; // to have a different size than GenEntryRulesDriven
};
template <typename T> …Run Code Online (Sandbox Code Playgroud) 我想通常使用libdl动态加载C ++。问题是在运行时识别已被名称篡改的符号。
如此处所述,一种解决方案是通过使用extern“ C”删除名称修饰。
http://www.tldp.org/HOWTO/C++-dlopen/theproblem.html
该解决方案具有将动态加载的资源限制为C样式接口的缺点。例如,动态加载的函数不能是重载函数。
什么是克服此限制的好方法?
一种可能的解决方案是使用链接函数命名库源代码的工具,以在需要链接库时获取修改后的名称。llvm是否为此提供工具?
可能一个笨拙的解决方案是使用函数签名的函数,使用具有签名的函数创建伪代码,将其与用于生成程序集的标志一起使用的编译器传递到编译器,解析输出以获取错误的名称并返回整齐的名称作为字符串。然后可以将字符串传递给dlsym()。
为了使问题更具体,这里有两个示例程序,它们说明了外部“ C”解决方案在不修改库代码的情况下无法动态加载的内容。第一个以传统的C ++方式动态链接库。第二个使用dlopen。在第一个程序中链接重载函数很简单。在第二个程序中没有简单的方法链接重载函数。
程序1:加载时动态链接
main.cpp
// forward declarations of functions that will be linked
void say(int);
void say(float);
int main() {
int myint = 3;
say(myint);
float myfloat = 5.0f;
say(myfloat);
}
Run Code Online (Sandbox Code Playgroud)
说
#include <iostream>
//extern "C" function signatures would collide
//extern "C" void say(int a) {
void say(int a) {
std::cout << "The int value is " << a << ".\n";
}
//extern "C" void say(float a) {
void say(float …Run Code Online (Sandbox Code Playgroud) 我们遇到了一些关于我没有找到任何文档的内容.看来,有很多班级成员等随着时间的推移会得到不同的名字.所以在一天之内,编译就会给出它,例如,
_ZThn1128_N9TESTCLASS14ContentChangedEv
然后经过一天的开发,它会得到一些不同的前缀,比如
_ZThn1140_N9TESTCLASS14ContentChangedEv
你知道吗,这里有多少前缀?我想,也许它与行号有某种联系,但不是.其次,我们如何确保,这不会随着时间的推移而变化?前缀肯定只是一些额外的,因为如果我改变了这个数字,那么demangled名称保持不变.
提前致谢.
我一直在尝试转储一组PE文件的所有导入的API函数调用。
我注意到大多数PE文件都有一组看起来很“奇怪”的导入功能。这些使我独特的函数调用数量大大增加,即使我觉得其中很多都是相同的函数调用。
经过进一步的研究,我发现这是由于名称处理所致,并且我目前正在寻找一种能够获取原始函数调用名称的解决方案(从某种意义上说,它更具可读性,也许可以减少我的数量)。唯一的函数调用)(如果可能),请使用Python而不是C ++。
我得到的一些例子:
?underflow@?$basic_streambuf@DU?$char_traits@D@std@@@std@@MAEHXZ
?setbuf@?$basic_streambuf@DU?$char_traits@D@std@@@std@@MAEPAV12@PAD_J@Z
??0exception@@QAE@ABQBD@Z
??0exception@@QAE@ABQBDH@Z
??0exception@@QAE@ABV0@@Z
??1exception@@UAE@XZ
Run Code Online (Sandbox Code Playgroud)
与
RegDeleteValueW
RegEnumKeyExW
RegCloseKey
RegQueryValueExW
RegSetValueExW
Run Code Online (Sandbox Code Playgroud)