如何从 C# 调用组装过程并返回结果?
Posted
技术标签:
【中文标题】如何从 C# 调用组装过程并返回结果?【英文标题】:How can I call an Assembly procedure from C# and get a result back? 【发布时间】:2021-11-18 19:09:59 【问题描述】:我正在尝试从 C# 中调用一个非常简单的组装过程以从中返回一些内容。
这是 C# 代码:
class Program
static void Main(string[] args)
ulong test = Start();
Console.WriteLine(test);
[DllImport(@"C:\dev\masm\basic.dll")]
private static extern ulong Start();
这是汇编 (MASM) 代码:
.code
Start proc
mov rax, 1
ret
Start endp
end
我使用以下命令从控制台组装和链接:
ml64 basic.asm /link /subsystem:console /entry:Start /out:basic.dll /dll /machine:x64
真正有趣的是,我能够成功调用一个打印“Hello, World!”的简单组装程序。但不返回任何东西。但是,当我尝试调用此过程时,即使我在 DLL 中指定了一个入口点,我仍然会收到此错误:
System.EntryPointNotFoundException: 'Unable to find an entry point named 'Start' in DLL 'C:\dev\masm\basic.dll'.'
我很可能错过了什么,但我想不通。
【问题讨论】:
您需要研究 P/Invoke 的机制,尤其是调用约定的工作原理。另请注意,Assembly 一词对 C# 和其他 .NET 程序员具有非常特殊的含义(它与打包有关,而不是操作码语言)。您的问题标题具有欺骗性。 不幸的是,“外部”没有为我做这件事,@zx485。是的,在 C# 和 .NET 的上下文中,“Assembly”这个词是完全正确的。感谢您提供有关 P/Invoke 的提示。 是的。我误会了。很抱歉。 【参考方案1】:你离得太近了!您需要将该过程标记为导出。
.code
Start proc export
mov rax, 1
ret
Start endp
end
Console.WriteLine(test);
现在打印 1
。
您可以通过使用开发控制台并运行DUMPBIN /HEADERS <DLL>
并在导出部分看到它来验证Start
过程是否已导出
File Type: DLL
Section contains the following exports for basic.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001000 Start
Summary
1000 .rdata
1000 .text
顺便说一句:您遇到的错误
System.EntryPointNotFoundException: 'Unable to find an entry point named 'Start' in DLL 'C:\dev\masm\basic.dll'.'
实际上与 dll 的入口点(通常称为 Main)无关,但它是一个 PInvoke 术语,基本上意味着“嘿,我们找不到你告诉我们要查找的导出的“Start”方法。”
【讨论】:
汉克,你是个传奇!我知道这个错误很奇怪,因为我能够顺利地调用另一个程序。非常感谢!以上是关于如何从 C# 调用组装过程并返回结果?的主要内容,如果未能解决你的问题,请参考以下文章
PHP如何调用SQLServer2012的存储过程并获取返回结果集及出参?
从存储过程执行 SQL Server 代理作业并返回作业结果
如何php调用oracle存储过程返回的是一个结果集,该怎么从php页面中吧数据循环输出呀