首页 文章

在C中呼叫公约名称管理

提问于
浏览
0

What I ask is NOT how to disable C++ name mangling (i know its extern "c"). The question is not about C++

据我所知,当我将一个函数声明为__stdcall时,它的名称应该像_FuncName @ 8中那样被破坏(对于两个int参数) . 当我将一个函数声明为__cdecl时,它应该像_FuncName一样被修改 .

听起来很好,但它真的像这样吗?

有两种情况我不明白:

1-)我在vc 2013中创建了一个dll,我在__cdecl函数上使用了__declspec(dllexport) . 它的导出没有任何下划线(只是FuncName) . 我没有.def文件或任何东西,也没有使用pragma export .

2-)大多数Windows API函数都是__stdcall . 但他们没有_或@ . 例如,它们像MessageBoxA一样导出,没有任何重整 .

那怎么解释呢?

1 回答

  • 1

    是的,Visual C将name decoration添加到C符号导出,以及C导出的名称修改 . 您可以在每个调用约定关键字的主题中阅读MSDN上的名称修饰约定 . extern "C" 链接规范实际上将导出的符号从C名称修改切换到C名称修饰,这不时给人们带来惊喜 .

    因此,对于导出函数的C文件,如果您非常非常仔细地阅读MSDN上的文档__cdecl,您会看到它提到“下划线字符(_)以名称为前缀, except when __cdecl functions that use C linkage are exported . ”" This still isn't as clear as it could be, since "导出“这里指的是DLL导出,它也适用于非功能符号,如导出的数据 . 这就是您在自己的代码中看到的内容 .

    我的推测是这些名称是未修饰的DLL导出,以使语言互操作容易 . 您会注意到,链接符号名称导出仍然具有前导下划线,如果转储.lib文件的导出,则可以看到该下划线 .

    对于第二种情况, __stdcall Windows API函数使用.def文件以特定名称导出 . 这就是你如何获得映射到API的窄字符和宽字符版本的默认名称 . 您可以使用 #pragma comment(linker, "/export:alias=_original") 获得相同的效果,但使用.def文件方法可能是最便携的 .

    你可以在Raymond Chen的The Old New Thing博客上找到关于The history of calling conventions的故事 .

相关问题