首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么要评论(链接器,"/export .“)未解析外部符号

为什么要评论(链接器,"/export .“)未解析外部符号
EN

Stack Overflow用户
提问于 2022-05-31 09:45:52
回答 1查看 327关注 0票数 1

头文件如下所示

代码语言:javascript
运行
复制
#define CoverWinAPI extern "C" __declspec(dllexport)


CoverWinAPI  BOOL RunDll();
CoverWinAPI void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,PROC pfnCurrent,PROC pfnNew,HMODULE hmodCaller);
#pragma comment(linker,"/export:MyCreateWindowExW=_MyCreateWindowExW@48")
CoverWinAPI  HWND WINAPI  MyCreateWindowExW(
        _In_opt_ DWORD     dwExStyle,
        _In_opt_ LPCWSTR lpClassName,
        _In_opt_ LPCWSTR lpWindowName,
        _In_ DWORD dwStyle,
        _In_ int X,
        _In_ int Y,
        _In_ int nWidth,
        _In_ int nHeight,
        _In_opt_ HWND hWndParent,
        _In_opt_ HMENU hMenu,
        _In_opt_ HINSTANCE hInstance,
        _In_opt_ LPVOID lpParam);

当我不使用#语用注释时,导出函数名是_MyCreateWindowExW@48。

但是当我使用#pragma comment(linker,"/export:MyCreateWindowExW=_MyCreateWindowExW@48")时,MSVC编译失败并显示unresolved external symbol _MyCreateWindowExW@48。是什么导致了这个错误?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-11 09:07:07

您遇到的问题是编译器修饰函数名称的方式造成的。_MyCreateWindowExW@48是一个x86风格的修饰名称,只对x86 build only 有效,它的x64对应项只是MyCreateWindowExW (x64只有一个类似于__cdecl的调用约定,即调用方负责管理堆栈分配)。

与正式文档相反,导出#pragma/EXPORT链接器选项都不使用未修饰的名称,它们都期望名称得到完整的修饰。我是这里提到的

小票

有几种从Dll导出的方法,例如:

  • __declspec(dllexport)
  • #pragma comment(linker,"/export:...")link.exe /EXPORT
  • DEF文件

通常只使用其中一个就足够了,所以在您的示例中,__declspec(dllexport)是多余的,考虑到它导出了一个修饰的名称,这不是您想要的。

解决方案1(海事组织繁琐)

使用#ifdef为每个平台提供适当的修饰名称:

代码语言:javascript
运行
复制
#define CoverWinAPI extern "C"

CoverWinAPI  BOOL RunDll();
CoverWinAPI void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller);

#ifndef _WIN64
#pragma comment(linker,"/export:MyCreateWindowExW=_MyCreateWindowExW@48")
#else
#pragma comment(linker,"/export:MyCreateWindowExW")
#endif

CoverWinAPI  HWND WINAPI  MyCreateWindowExW(...);

解决方案2(建议)

将DEF文件添加到项目中:

代码语言:javascript
运行
复制
LIBRARY   CoverWinAPI
EXPORTS
    MyCreateWindowExW
    RunDll
    ReplaceIATEntryInOneMod

然后您的声明可以重写如下:

代码语言:javascript
运行
复制
#define CoverWinAPI WINAPI

BOOL CoverWinAPI RunDll();
void CoverWinAPI ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller);

HWND CoverWinAPI  MyCreateWindowExW(...);

这是因为链接器确实试图匹配DEF文件条目与修饰和未修饰的名称。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72445583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档