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

如何在C#中调用x64汇编过程 直接及C++间接调用问题咨询

问题1解答

C# 可以直接调用MASM编译生成的DLL,你之前调用抛出二进制不兼容异常通常是以下原因导致:

  • 项目架构不统一:比如C#项目设置为Any CPU,而ASM DLL编译为x86/x64单架构,或者两边架构完全不匹配
  • 调用约定不匹配:C#的DllImport默认调用约定是StdCall,若ASM导出函数使用其他调用约定且没有显式声明就会报错
  • 导出函数名不匹配:未使用def文件或者声明导出规范,导致MASM编译时对函数名做了修饰,C#找不到对应入口

问题2解答

你返回随机值的核心原因是调用约定不匹配,具体问题出在:
你在C++中定义的函数指针是__stdcall类型,但是你的ASM代码既没有指定调用约定,也没有按照__stdcall的规则清理栈:

  1. __stdcall要求被调用方负责清理参数栈,你传入两个DWORD参数共8字节,ASM的ret指令需要手动释放这部分栈空间
  2. 你当前ASM的实现默认使用CDECL调用约定,由调用方清理栈,C++用__stdcall去调用的话会导致栈不平衡,返回值读取异常

修复方案二选一即可:

方案1:修改ASM代码适配__stdcall约定

你的Main.asm代码调整为:

.386
.model flat, stdcall
.stack 4096

MyProc1 proc x: DWORD, y: DWORD
mov EAX, x
mov ECX, y
add EAX, ECX
ret 8 ; 两个DWORD参数共8字节,被调用方清理栈
MyProc1 endp
end

同时确保你的def文件导出名正确,ASM项目编译架构和C++、C#项目统一。

方案2:修改C++的函数指针约定为CDECL匹配ASM默认实现

将C++中的函数指针定义修改为:

typedef int(__cdecl* f_MyProc1)(DWORD, DWORD);

不需要修改ASM代码即可正常运行。

额外说明

如果要直接在C#中调用ASM DLL,只要保证导出函数名正确、调用约定匹配、架构统一即可,不需要经过C++中转,示例代码:

// 对应__stdcall约定的ASM函数
[DllImport("Algorithm.Asm.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MyProc1(int x, int y);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:45:02