4

コールバック関数として使用される関数ポインターを持つエクスポート関数を含む C++ で記述された DLL があります。

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

DLL 関数を呼び出すために使用したい CSharp アプリケーションがあります。

// 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 ; 
    }
}

上記のコードの問題は、次のエラー メッセージでアプリケーションがクラッシュすることです。

'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).

次に何をすればよいかわかりません。

私の質問は:

  • C# アプリケーションから Callback ポインターを含む C++ DLL 関数を呼び出す正しい方法は何ですか?
4

1 に答える 1

3

これは、デフォルトでは の関数の呼び出し規約は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 );
    // ...
}
于 2012-11-08T00:09:16.077 に答える