You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NativeAOT ILC编译x86时导出符号带@后缀致链接错误问题

x86平台下.NET导出函数与C++链接符号不匹配问题

问题场景

C#导出函数至DLL

使用[UnmanagedCallersOnly]特性导出函数:

public class Symbol {
   [UnmanagedCallersOnly(EntryPoint = "Console_Symbol_ReverseColors")]
   public static void ReverseColors(nint sym) {
       // 业务逻辑
   }
}

C++导入函数

在C++中声明导入该函数:

extern "C" __declspec(dllimport) void Console_Symbol_ReverseColors(void*);

编译与错误情况

  • 编译x64版本时,使用命令:
    dotnet publish -p:NativeLib=Shared -p:SelfContained=true -r win-x64 -c Release
    
    链接C++代码正常通过。
  • 编译x86版本时,使用命令:
    dotnet publish -p:NativeLib=Shared -p:SelfContained=true -r win-x86 -c Release
    
    链接C++代码时触发LNK2019未定义引用错误:
    Console.obj : error LNK2019: unresolved external symbol __imp__Console_Symbol_ReverseColors referenced in function "xxx"
    

通过dumpbin查看生成的lib文件符号:

  • x64版本符号:__imp_Console_Symbol_ReverseColors
  • x86版本符号:__imp__Console_Symbol_ReverseColors@4

原因解析

这是Windows平台x86与x64调用约定的差异导致的:

  • x64平台:Windows规定了统一的调用约定(本质是fastcall),所有函数导出时不会添加参数字节数的后缀修饰,因此符号格式统一。
  • x86平台:.NET的[UnmanagedCallersOnly]特性默认使用stdcall调用约定,这种约定会在导出符号后添加@N后缀(N是参数总字节数,这里参数是一个指针,占4字节,所以是@4)。而C++代码中未指定调用约定时,默认使用cdecl,编译器会尝试查找不带@N后缀的符号,两者不匹配就触发了链接错误。

修复方案

方案1:修改C++导入声明,匹配stdcall调用约定

在C++函数声明中显式指定__stdcall(或使用跨平台的WINAPI宏,它在x86下映射为__stdcall,x64下映射为统一调用约定):

// 方式1:直接指定__stdcall
extern "C" __declspec(dllimport) void __stdcall Console_Symbol_ReverseColors(void*);

// 方式2:使用WINAPI宏,兼容x86/x64
extern "C" __declspec(dllimport) void WINAPI Console_Symbol_ReverseColors(void*);

方案2:修改C#导出时指定Cdecl调用约定

在[UnmanagedCallersOnly]中通过CallConvs参数指定使用cdecl调用约定,让x86下导出的符号不带@N后缀,匹配C++默认的调用约定:

public class Symbol {
   [UnmanagedCallersOnly(EntryPoint = "Console_Symbol_ReverseColors", 
                         CallConvs = new[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
   public static void ReverseColors(nint sym) {
       // 业务逻辑
   }
}

内容的提问来源于stack exchange,提问作者Stas Badzi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:36:08