如何在C#中调用MASM汇编过程并获取返回值?
问题根因
- 你混淆了DLL入口点和可导出调用函数两个概念:你给链接器指定的
/entry:Start是DLL被系统加载时的初始化入口,不是给外部调用的导出函数入口。你之前可以成功调用的HelloWorld汇编过程,大概率是已经做了导出配置,才可以正常被识别。 - 你当前的汇编代码没有将
Start函数声明为导出函数,DLL的导出表中没有对应符号,所以C#调用时触发入口点找不到的异常。
修复步骤
1. 声明导出函数
有两种常用方式选其一即可:
方式1:直接在汇编代码中加导出标识
在过程定义后加上EXPORT指令,明确告诉汇编器该函数需要被导出到DLL的导出表中:
.code Start proc EXPORT mov rax, 1 ret Start endp end
方式2:通过def文件定义导出表
新建名为basic.def的文件,内容如下,这种方式导出符号更稳定:
EXPORTS Start
2. 修正汇编链接命令
删除错误的/entry:Start参数,DLL默认的系统入口点已经可以满足需求,不需要自定义入口:
# 用方式1导出时用这个命令 ml64 basic.asm /link /subsystem:console /out:basic.dll /dll /machine:x64 # 用方式2导出时用这个命令,增加def文件参数 ml64 basic.asm /link /subsystem:console /def:basic.def /out:basic.dll /dll /machine:x64
3. 验证导出结果
可通过VS开发人员命令提示符的dumpbin工具验证导出是否生效:
dumpbin /exports C:\dev\masm\basic.dll
如果输出的导出列表中存在Start符号,即可正常被C#调用。
补充说明
微软x64调用约定规定整数返回值存放在RAX寄存器中,你的汇编代码写法完全符合约定,C#端接收到的返回值会是正确的1。
内容的提问来源于stack exchange,提问作者Ivan Spajić
相关产品推荐
相关产品推荐

