在 C# 中调用 UnmanagedFunctionPointer 以实现自定义调用约定
我在 DLL 中有一个函数:
char __usercall MyUserCallFunction<al>(int arg1<esi>)
因为我讨厌自己,所以我想使用 P/Invoke 从 C# 中调用它。
通常,这可以通过获取函数委托来完成,例如:
[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Auto, SetLastError = true)]
public delegate char DMyUserCallFunction(IntPtr a1);
然后通过执行以下操作来调用它:
var MyFunctionPointer = (DMyUserCallFunction)Marshal.GetDelegateForFunctionPointer(AddressOfFunction, typeof(DMyUserCallFunction));
MyFunctionPointer(IntPtr.Zero);
但是,对于自定义用户调用约定,这将导致程序崩溃。是否有某种方法可以使用不安全代码或某种包装函数来完成此操作,将委托放置到位,但不会强迫我编写 C++ DLL?
谢谢!
编辑:
按照 dtb 的建议,我创建了一个非常小的 C++ DLL,通过 P/Invoke 使用它来调用该函数。对于任何好奇的人来说,C++ 中的函数最终看起来像这样:
extern "C" __declspec(dllexport) int __stdcall callUsercallFunction(int functionPointer, int arg1 )
{
int retVal;
_asm
{
mov esi, arg1
call functionPointer
mov retVal, eax
}
//Fake returning al, the lower byte of eax
return retVal & 0x000000FF;
}
I have a function in a DLL:
char __usercall MyUserCallFunction<al>(int arg1<esi>)
Because I hate myself I'd like to call this from within C# using P/Invoke.
Normally this can be done by getting a function delegate, a la:
[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Auto, SetLastError = true)]
public delegate char DMyUserCallFunction(IntPtr a1);
And then invoking it by doing:
var MyFunctionPointer = (DMyUserCallFunction)Marshal.GetDelegateForFunctionPointer(AddressOfFunction, typeof(DMyUserCallFunction));
MyFunctionPointer(IntPtr.Zero);
For custom user calling conventions, however, this will cause the program to crash. Is there some sort of way I can do this using unsafe code or some sort of wrapper function that puts the delegates in place, but doesn't force me to write a C++ DLL?
Thanks!
Edit:
As suggested by dtb, I created a very small C++ DLL which I use via P/Invoke to call the function. For anyone curious the function in C++ ends up looking like:
extern "C" __declspec(dllexport) int __stdcall callUsercallFunction(int functionPointer, int arg1 )
{
int retVal;
_asm
{
mov esi, arg1
call functionPointer
mov retVal, eax
}
//Fake returning al, the lower byte of eax
return retVal & 0x000000FF;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 C# 中实现自定义调用约定是不可能的。您必须在本机 DLL 或 C++/CLI DLL 中执行此操作。
There's no hope of implementing custom calling conventions in C#. You must do this in either a native DLL or a C++/CLI DLL.