在 C# 中调用 UnmanagedFunctionPointer 以实现自定义调用约定

发布于 2024-12-06 09:27:30 字数 1117 浏览 1 评论 0原文

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

稳稳的幸福 2024-12-13 09:27:30

在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文