P/Invoke 和 C# 的自定义调用约定
我有一个业务案例,在使用 P/Invoke 时,我需要能够指定自己的调用约定。 具体来说,我有一个使用非标准 ABI 的遗留 dll,并且我需要能够指定每个函数的调用约定。
例如,该 dll 中的一个函数通过 EAX 和 EBX 接受前两个参数,其余参数通过堆栈接受。 另一个函数通过 ECX 接受一个参数,其余的在堆栈上。 我有几百个这样的函数,并且希望避免编写自己的中间桥 DLL 来访问这些函数。
我的另一个选择是手动滚动我自己的自定义 P/Invoke,由于显而易见的原因,这是不可取的。
任何帮助表示赞赏,谢谢,
I have a business case whereby I need to be able to specify my own calling convention when using P/Invoke. Specifically, I have a legacy dll which uses a non-standard ABI, and I need to able to specify the calling convention for each function.
For example, one function in this dll accepts its first two arguments via EAX and EBX, with the rest via stack. Another function accepts one argument via ECX, with the rest on the stack. I have a few hundred of these functions, and would like to avoid writing my own intermediate bridge DLL in order to access these functions.
My other option would be to hand-roll my own custom P/Invoke, which is undesirable for obvious reasons.
Any help is appreciated, thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不明白您对自定义 P/Invoke 的意思,但我不明白如果没有带有内联汇编的非托管 C++,您如何摆脱困境。 然而,由于几乎所有内容都作为 32 位值传递,因此您可能只需为每个函数签名编写一个代理,而不是每个函数一个代理。 或者您可以编写一个代码生成器,从 XML 生成代理。 不过,我不认为这个版本太不可取,因为所有代理函数都非常简单:
I don't understand what you mean with custom P/Invoke, but I can't see how you could get away without non-managed C++ with inline assembly. However, since almost everything is passed as 32-bit values, you might get away with writing only one proxy for each function signature, as apposed to one per function. Or you could write a code generator which generates proxies from XML. I can't see this version being too undesirable though, since all proxy functions will be really simple:
我相当确定,如果没有单独的 dll,就没有内置方法可以完成您想要的任务。 除了运行时系统支持的调用约定之外,我还没有看到任何指定调用约定的方法。
I'm fairly certain there is no builtin way of accomplishing what you want without a separate dll. I've not seen a way to specify a calling convention other than what the runtime system supports.
我不久前正在学习调用约定,并编写了一些代码来转换调用约定。 该代码从特殊的 C# 包装器调用,包装器库使用反射发射(无法使 Marshal.getdelegateforfunctionpointer 工作)为特殊的裸存根方法发出新的 p/invoke 方法。 它修复参数,然后调用实际方法。
这是c代码。 我手头没有 C# 部分:( 当时我也在学习汇编程序,所以代码可能很糟糕:)
I was learning about calling conventions a while back and wrote some code to convert calling conventions. The code gets called from a special C# wrapper, the wrapper library uses reflection emit (couldn't get Marshal.getdelegateforfunctionpointer working) to emit a new p/invoke method for special naked stub method. It fixes up parameters and then invokes the actually method.
Here is the c code. I don't have the C# part handy :( I was learning assembler too at the time so the code might suck :)