简体   繁体   English

调用包含C#函数指针的DLL函数

[英]Calling a DLL function that contains a function pointer from C#

I have a DLL that is written in C++ that includes exported function that has a function pointers to be used as callback function. 我有一个用C ++编写的DLL,其中包含导出函数,该函数具有可用作回调函数的函数指针。

// C++ 
DllExport unsigned int DllFunctionPointer( unsigned int i, unsigned int (*TimesThree)( unsigned int number ) ) {
    return TimesThree( i )  ; 
}

I have a CSharp application that I would like to use to invoke the DLL functions. 我有一个CSharp应用程序,我想用它来调用DLL函数。

// C#
public unsafe delegate System.UInt32 CallBack( System.UInt32 number ); 
class Program
{
    [DllImport("SimpleDLL.dll")]
    public static extern System.UInt32 DllFunctionPointer( System.UInt32 i, CallBack cb) ;

    static unsafe void Main(string[] args)
    {
        System.UInt32 j = 3;
        System.UInt32 jRet = DllFunctionPointer(j, CallBack );
        System.Console.WriteLine("j={0}, jRet={1}", j, jRet); 
    }

    static System.UInt32 CallBack( System.UInt32 number ) {
        return number * 3 ; 
    }
}

The problem with the above code is that the application crashes with the following error message. 上述代码的问题是应用程序崩溃时出现以下错误消息。

'CallingACallbackFromADLL.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\XXXX\CallingACallbackFromADLL.exe', Symbols loaded.
Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\XXXX\CallingACallbackFromADLL.vshost.exe'.
Additional Information: A call to PInvoke function 'CallingACallbackFromADLL!CallingACallbackFromADLL.Program::DllFunction' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

The program '[9136] CallingACallbackFromADLL.vshost.exe: Managed (v4.0.30319)' has exited with code 1073741855 (0x4000001f).

I am not sure what to do next. 我不知道下一步该做什么。

My question is: 我的问题是:

  • What is the correct way to call a C++ DLL function that contains a Callback pointer from a C# application. 调用包含C#应用程序的Callback指针的C ++ DLL函数的正确方法是什么。

This is because by default calling convention of functions in C# is __stdcall but in C/C++ default is __cdecl , so you should change calling convention of your function as follow: 这是因为默认情况下C#中函数的调用约定是__stdcall但是在C/C++默认是__cdecl ,所以你应该改变函数的调用约定如下:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void TimesTree( uint frame );
[DllImport("SimpleDLL.dll")]
public static extern System.UInt32 DllFunctionPointer( uint i,
    [MarshalAs(UnmanagedType.FunctionPtr)] TimesTree callback ) ;

static unsafe void Main(string[] args)
{
    // ...
    System.UInt32 jRet = DllFunctionPointer(j, CallBack );
    // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM