Class 用C+重新嵌入DLL方法变量+;在visual studio中的ABI级别 我有一个C++第三方DLL,我想用我自己做的一个DLL来代替它。 这是一个无尘室类型的练习,仅用于学习目的;我希望制作一个替代DLL,可以与与原始DLL链接的程序一起使用,而无需重新编译应用程序

Class 用C+重新嵌入DLL方法变量+;在visual studio中的ABI级别 我有一个C++第三方DLL,我想用我自己做的一个DLL来代替它。 这是一个无尘室类型的练习,仅用于学习目的;我希望制作一个替代DLL,可以与与原始DLL链接的程序一起使用,而无需重新编译应用程序,class,visual-c++,dll,static,Class,Visual C++,Dll,Static,我使用与生成原始DLL相同的visual studio编译器版本(9),但我没有该DLL的原始源代码 DLL由C++类和一些外部“C”函数组成,以处理构造函数/析构函数,从而使所有内存管理与DLL隔离。 我使用dependency walker检查原始DLL,并对链接器符号进行demangle/取消修饰——并尝试为类和方法编写原型;然后我编写了一个python脚本来获取从我的类编译的目标代码——并生成一个.def文件,从我的obj代码中选择与原始DLL导出相比最接近的损坏符号;(允许一些限定符

我使用与生成原始DLL相同的visual studio编译器版本(9),但我没有该DLL的原始源代码

DLL由C++类和一些外部“C”函数组成,以处理构造函数/析构函数,从而使所有内存管理与DLL隔离。 我使用dependency walker检查原始DLL,并对链接器符号进行demangle/取消修饰——并尝试为类和方法编写原型;然后我编写了一个python脚本来获取从我的类编译的目标代码——并生成一个.def文件,从我的obj代码中选择与原始DLL导出相比最接近的损坏符号;(允许一些限定符变体,但不允许名称变体),然后我使用该.def文件从obj代码构建了一个DLL,以便在DLL中具有相同的ABI顺序

在列出类型时,dependency walker无法分辨我的DLL和原始DLL之间的差异——尽管我想解决的几个损坏名称之间存在细微差异

一个成员很难理解,因为它不是一个函数,而是假定的成员数据,例如:一个修饰的?pzSambaAddress@HWInterface@@2PBDB显示为:

char const * const HWInterface::pzSambaAddress ; // in dependency walker
我不确定dependency walker是否解码错了,因为 我不知道如何在我的头文件中远程实现这样的东西,将符号导出到.obj文件,更不用说DLL了

什么样的定义可以创造这样的东西

如果我在头文件中键入它(如上所示),它是一个常量字符串——因此我认为它必须在构造函数方法中初始化,如下所示:

HWInterface::HWInterface(HWInterface const & iface) : pzSambaAddress("dummy") {
    std :: cout << this -> pzSambaAddress; // access it, to force compiler
}
然后这个名字就变成了:?pzSambaAddress@HWInterface@@2QBDB

但是依赖沃克并没有说它是静态的。。。也不是完全损坏的@2QBDB@@2PBDB。。。这也意味着我不能再使用构造函数初始化单个实例

HWInterface.cpp(25):错误C2438:“pzSambaAddress”:无法通过构造函数初始化静态类数据

那么Q1:静态常量是导出符号的原因吗?依赖项walker只是不说“静态”——或者有其他生成/初始化它的方法吗

第二:

有没有更好的方法来要求和提供关于深奥限定词的信息

当我在一个对象文件上运行dumpbin时,我得到了依赖项walker没有显示的所有类型的限定符(在其他符号上,而不是我们所讨论的示例上)。 dumpbin.exe/myOwnFile.obj

但是由于我没有原始DLL的obj文件,也没有.lib,所以这个开关不起作用。在DLL上运行dumpbin.exe/symbols不会给我任何帮助。 在DLL上运行dumpbin.exe/exports只会给出损坏的名称。 还有一个VC++控制台应用程序“undname.exe”,但它通常根本不会取消在命令行上传递的名称,而是返回大部分仍然损坏的名称

我在网上查阅了很多信息,但我只找到了部分准确/不完整的信息,这还不足以解决我刚才提到的问题

有什么想法可以找到一个更详细、更精确的Deangangle程序,用于VisualC++?
class HWInterface {
    public:
    __declspec(dllexport) 
    static char const *  pzSambaAddress;
};

char const*  HWInterface::pzSambaAddress = "hello";
然后:

您可以使用MSVC附带的
undname
实用程序解码损坏的名称:

C:\temp>undname ?pzSambaAddress@HWInterface@@2PBDB
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of :- "?pzSambaAddress@HWInterface@@2PBDB"
is :- "public: static char const * const HWInterface::pzSambaAddress"
但是,您会注意到,
undname
表示其中应该有一个额外的
const
。正如您所看到的,添加额外的
const
会使您得到一个稍微不同的名称(末尾用“Q”而不是“P”:

使用
静态字符常量*const
而不是
静态字符常量*
生成
?pzSambaAddress@HWInterface@@2QBDB

undname
从C运行时导入一个函数,
\u unDNameEx
,我假设该函数用于demangle名称(并且我假设Dependency Walker也使用它-显然是通过DBGHELP.DLL中的接口)。看起来demangler中有一个bug


GNU工具有一个类似的实用程序,
c++filt
,用于解码g++损坏的名称。

是的,我可以清楚地看到Visual studio提供的一些未修饰库中存在一个bug;您使用的是什么版本?我拥有的undname.exe的最佳版本是md5sum:ff8f053c9a896be915b4cb9b5f6feb3e,并且它并不总是与正确取消命名项目;例如:undname?bIsBluetoothAddress@HWInterface@@阿联酋NABV?@DV?@DV@D@ATL@@@@@ATL@@@Z将返回吗?bIsBluetoothAddress@HWInterface@@阿联酋NABV?@DV?@DV@D@ATL@@@@@ATL@@@Z的名称绝对没有取消修饰。我想我找到了问题所在;有不同版本的msvcrt.dll可以在我的系统上运行;我很可能使用的是旧版本。不……我显式链接到msvcrt.dll版本7.0.7601.17744 md5:9dc80a8aaaaac397bdab3c67165a824,它也有完全相同的问题。奇怪的是,依赖项walker比直接链接到dll版本7的exe做得更好。当我在自身上运行依赖项walker时(最新版本),它没有显示自己链接到DBGHELP.DLL或msvcrt.DLL。因此,我认为较新的dependency walker可能不使用microsoft的库。它报告:bool HWInterface::bIsBluetoothAddress(类ATL::CStringT const&)
C:\temp>cl /LD test.cpp
...

C:\temp>dumpbin /exports test.dll
...
Dump of file test.dll
...    
    ordinal hint RVA      name

          1    0 00008000 ?pzSambaAddress@HWInterface@@2PBDB
C:\temp>undname ?pzSambaAddress@HWInterface@@2PBDB
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of :- "?pzSambaAddress@HWInterface@@2PBDB"
is :- "public: static char const * const HWInterface::pzSambaAddress"