问题标签 [name-decoration]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 导出未修饰的函数名称
我在这里阅读了几篇关于名称修饰/装饰的文章,并且一直遇到不一致的情况,所以我想我会问一个非常集中的问题,看看会发生什么。
我正在努力提高学习曲线,最终能够在 VS2013 中创建一个 dll,该 dll 可由在非常旧的 Borland C++ 编译器上生成的代码使用。第一步是在VS2013中构建一个可以“说话”的exe和dll。我想要未修饰的函数名称。所以我创建了一个带有一个导出函数的 dll。
我的有限理解是:
- extern "C" 表示没有装饰
- __declspec(dllexport) 表示导出函数
- __cdecl 指定调用签名(参数如何放入堆栈等)
当我使用 DependencyWalker 或 Dumpbin /EXPORTS 检查 dll 时,函数名称未修饰。耶。
这是 exe 中尝试调用 dll 中导出函数的代码:
但是,当我尝试构建 exe 时,出现链接器错误。
请注意,exe 提到_BasicFileOpen。我对此感到困惑。我已经正确地指出了由 dll 构建生成的 lib 文件。我在 exe 中包含了 dll 函数的头文件。为什么链接器不理解导出函数的名称?为什么它认为函数名被修饰了?顺便说一句,使用 .def 文件似乎没有任何区别。
任何意见表示赞赏。
MBB
c++ - 如何从 DLL 导出中删除下划线
我想替换一个我没有完整源代码(但函数声明)的 DLL。应用程序在运行时加载此 DLL 并GetProcAddress
使用(所有)函数名称进行调用。(所以我必须将函数命名为完全相同)。
我创建了一个新的 DLL(在 MS VC2013 中)并编写了函数。但是我在正确导出它们时遇到问题。
在原始 DLL 中,它们被定义,_stdcall
但它们的名称不以下划线开头。
如果我像这样在 .def 文件中指定名称,testfunc@4=testfunc
则 @ 后面的所有内容都将被删除。
如何在 VS2013 中指定我想要一个 DLL 导出,例如testfunc@4
?
winapi - 当名称可能被修饰时使用 GetProcAddress
GetProcAddress()
在 32 位 DLL 上使用的正确方法是什么?在win32上,共有三种调用约定,cdecl、stdcall和fastcall。如果 DLL 中的函数是foo
他们将通过以下方式装饰名称_foo
,_foo@N
并且@foo@N
.
但是如果 dll 的作者使用了 .def 文件,那么导出的名称将被更改为只是“foo”而没有任何修饰。
这给我带来了麻烦,因为如果我想foo
从使用 stdcall 的 dll 加载,我应该使用修饰名称:
或未装饰的:
? 我应该猜吗?我查看了许多 32 位 DLL 文件(stdcall 和 cdecl),它们似乎都导出了未修饰的名称。但是你能假设情况总是如此吗?
c - C中的名称装饰
是否有任何标准的授权名称装饰?
据我所知,大多数(全部?)符合标准的实现都会在每个导出符号的名称中添加下划线前缀。这是由 C、POSIX 或其他标准保证的吗?
c++ - 函数的修饰名称生成不当
我正在尝试使用 Visual Studio 2017(从 Visual Studio 6.0 升级)将一些第三方 C++ 代码编译到我的 32 位 C++ 应用程序中。我有来自第三方的 .h 文件和 .lib 文件。链接器正在查找库,但没有找到其中包含的修饰名称。这似乎是因为编译器正在用“char”替换“__int8”。
链接器错误是:
该函数在 .h 中定义:
API_RETURN_TYPE 在 .h 中定义:
使用 dumpbin /exports,我可以看到我的 lib 和关联的 dll 导出 Check_The_Thing:
使用 undname,我可以看到 lib 中的修饰名称正确评估:
但是编译器生成的修饰名称没有正确评估(基于代码):
根据https://en.wikiversity.org/wiki/Visual_C%2B%2B_name_mangling,YACXZ 中的“C”计算为“signed char”,“_D”计算为“__int8”。我无法弄清楚为什么编译器将 API_RETURN_TYPE 解释为“char”而不是“__int8”。很明显,lib/dll 导出应该有“_C”而不是“_D”,因为 API_RETURN_TYPE 是“签名的 __int8”,而不仅仅是“__int8”。
我摆弄了一堆编译器设置,但没有运气。正如这里所建议的(在 dll 中找不到修饰的函数名称),我确保我使用的是 MBCS 而不是 Unicode(之前未设置),但这也没有什么区别。
专门将 API_RETURN_TYPE 定义为 __int8 没有区别,只是将“C”更改为“D”(进度!),同样 undname 将返回类型显示为“char”而不是“signed char”。将函数定义的返回类型更改为 __int8 与更改 API_RETURN_TYPE 的效果相同。
所以,我的问题是:如何强制编译器使用“__int8”(或“_D”)而不是 char(“D”)正确定义我的导出?
旁注:在使用 __int16、__int32 和 __int64 的情况下,链接器错误是相同的。
编辑:实际上,该库定义了 __int64 类型,但我没有使用任何类型。没有任何 __int64 链接器错误。
c++ - Visual C++ 2015 不生成前导“_”
我现在创建 dll 已经很长时间了,但是我对我的新项目中出现的一个问题有点好奇,第一个带有VS C++ 2015
.
它没什么特别的,一个简单的 C++ 项目,创建一个 windows 32/64 位 dll。我正在像这样将我的函数导出为“C”(没有 DEF 文件):
但是我的应用程序加载 dll 失败了Can not find _foo()
。使用 Dependency Walker 检查 dll 显示我foo()
已导出,但没有强制性的_
.
我找不到对创建导出函数名称有影响的编译器/链接器选项。
c++ - 将英特尔 Visual Fortran 程序链接到 C++ 函数时出现问题
我正在尝试将一个非常简单的 C++ 函数链接到一个非常简单的 Intel Visual Fortran 程序。
Fortran 程序在一个名为 VFTestBed.f90 的文件中如下所示):
Fortran 接口块如下所示(在名为 interfaces.f90 的文件中):
C++ 函数如下所示(在名为 cppresponder.cpp 的文件中):
我在谷歌上研究了这个问题,并尝试了各种设置、声明、装饰等的几十种排列和组合,但都无济于事。事实上,许多帖子都很长而且相当复杂,而且往往似乎没有得出一个成功的结论。
除其他外,我尝试过:
- 使 C++ 代码成为 .LIB
- 使 C++ 代码成为 .DLL
- 使用各种形式的 !DEC$ATTRIBUTES DECORATE, ALIAS: "SimpleTest1"
- 使用 BIND(C, ...)
- 使用普通别名
- 使用修饰别名
- 使用 DUMPBIN 查看 .DLL 中的符号
- 使用前导外部“C”
- 编译为 C 代码(禁用所有 C++ 结构)
还有很多其他的东西。我已经尝试了所有应该对其他海报有用的东西,但绝对没有运气。
无论我做什么,我都会收到一条链接器错误消息 LNK2019,关于函数 _MAIN__ 中引用的未解析的外部符号 _SIMPLETEST1
根据英特尔网站,我在 CppResponder.DLL 中添加了,就像在源文件中添加一样。
如果重要的话,我正在使用适用于 Windows 的 Visual Studio Enterprise 2017 和 Intel Parallel Studio XE 2016 Update 4 composer Edition,它们都在 64 位 Windows 8.1 机器上运行。
假设 Intel Fortran 确实可以调用 C++ 函数(我假设它可以),那么我一定是在某处缺少开关或设置。我已经使用 Visual Studio 提供的默认值设置了 Fortran 和 C++ 项目。两个项目都设置为 Release | x86。
当然,这真的不是那么难的事情。我在这上面花了大约 12 个小时,但没有什么可展示的。我在 Fortran 方面拥有数十年的经验,但对 C++ 还是很陌生。
有没有人这样做过,并愿意带我了解你是如何做到的?
提前致谢,
鲍勃·基泽
c++ - 在 Visual Studio 中链接到 C++(32 位)中去修饰的 DLL 名称时出现问题
我有一个 C++ 中的 DSP 函数库,我想在运行时动态链接到它们。我正在使用PDLL.h方法将我的类(例如 FFT)包装到 C 风格的函数中,并在其他 C++ 应用程序中动态加载它们。我想在 .NET 应用程序和 COM 组件中使用这些函数,所以我必须使用__stdcall
32 位构建中的名称来装饰名称。
为了取消装饰名称,我使用了这里提到的技巧:C++ DLL Export: Decorated/Mangled names(wqw 的答案,第 2 下)。例如,在我的库的 .h 文件中,我声明了我的包装函数:
这确实有效,当我使用依赖项walker 查看 dll 时,我看到 DoFFT 和 _DoFFT@12 都有一个条目。
我遇到的问题是,当我尝试构建一个链接到该库的项目时(动态地,在运行时,根本不使用 .lib 文件),我的 dll 中的所有函数都会出现链接器错误,即:
我不明白为什么会这样。首先,符号 _DoFFT@12 确实存在(根据dependency walker),其次,为什么链接器首先要寻找它?我在运行时链接到它,而不是在编译时,所以我的项目怎么知道这个符号?
所有函数都使用相同的宏链声明,这些宏可以简化为(例如):
在客户端声明与库无关。
c++ - __FUNCDNAME__ 返回错误的修饰函数名
函数签名是:
函数内使用的__FUNCDNAME__宏返回修饰函数名:
- 图像内的真实函数名:?Test@@YGXPADH@Z
- __FUNCDNAME__ 返回:?Test@@YGXPADH@Z
当/clr选项打开时(项目 > 属性 > 常规 > 公共语言运行时支持 > /clr)__FUNCDNAME__ 宏不返回真正的修饰函数名称:
- 图像内的真实函数名:?Test@@YGXPADH@Z
- __FUNCDNAME__ 返回:?Test@@ $$F YGXPADH@Z __FUNCDNAME__ 宏不返回真正的修饰函数名。
这使得无法使用#pragma 注释指令直接从代码中导出 DLL 中的函数而无需名称修饰:
返回链接器错误 LNK1242 '?Test@@$$FYGXPADH@Z' 是无效的导出符号名称。
c++ - 为什么微软链接器修改修饰的导出名称?
我正在尝试使用此处推荐的“wrappit”工具制作代理 dll 。工具“wrappit”正确创建为 .cpp:
作为随附的 .def 文件:
但是在我构建了生成的库之后,构建的 dll 中所有导出函数的名称似乎都在参数描述开始时被截断了。所以??0CFileFormat@@QAE@XZ
转入??0CFileFormat
,?GetSkipListingForSPlanner@EnvironVar@@SAKXZ
转入?GetSkipListingForSPlanner@EnvironVar
等等。结果,由于缺少必要的导出,我的代理 dll 无法加载。为什么会发生这种情况,我应该怎么做才能解决它?