[C ++对C#的回调函数

问题描述 投票:0回答:1

我想将功能从C ++重写为C#。我没有使用C ++的经验,但这就是我已经写的。带有某些功能的DLL导入已经可以使用。但是这种回调使我很挣扎。请帮我:)

c ++代码:

/* Structure for PBORCA_CompileEntryImport callback function. */
typedef struct pborca_comperr  
{
    INT     iLevel;                         
    LPTSTR   lpszMessageNumber;             
    LPTSTR   lpszMessageText;               
    UINT    iColumnNumber;                  
    UINT    iLineNumber;                   

} PBORCA_COMPERR, FAR *PPBORCA_COMPERR;


/* Prototype for PBORCA_CompileEntryImport callback function.  */            
typedef PBCALLBACK(void, *PBORCA_ERRPROC) ( PPBORCA_COMPERR, LPVOID );

我的C#代码:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct PBORCA_COMPERR
{
    public int iLevel;                            
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string lpszMessageNumber;               
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string lpszMessageText;                  
    public int iColumnNumber;                       
    public int iLineNumber;                        
}

private delegate void PBORCA_CALLBACK(IntPtr pDirEntry, IntPtr lpUserData);
c# c++ callback dllimport
1个回答
0
投票

据我了解,有几种可能的方法。这将取决于您的要求。

选项1)使用IntPtrMarshal.GetFunctionPointerForDelegate

// A template of the function you want other code to call
// Your calling convention may be different
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] // note calling convention
delegate void PBORCA_CALLBACK(IntPtr pDirEntry, IntPtr lpUserData);  

class Orca
{
    [DllImport("LibraryName.dll")]
    private static extern int PBORCA_CompileEntryImport(
        IntPtr hORCASession,
        ...
        long lEntrySyntaxBuffSize,
        IntPtr pCompErrorProc, // note the IntPtr
        IntPtr pUserData);

    // An implementation of the function delegate (this will be called)
    private static void StaticImpOfTheCallback(IntPtr pDirEntry, IntPtr lpUserData)
    {
        // write code here (Notice: I'm a static function)
    }

    // An implementation of the function delegate (this will be called)
    private void NonStaticImpOfTheCallback(IntPtr pDirEntry, IntPtr lpUserData)
    {
        // write code here (Notice: I'm not static)
    }

    // Create a delegate object which will link the callback function
    private PBORCA_CALLBACK staticCallbackDel = StaticImpOfTheCallback; 

    public void SomeCallingFunction()
    {
        PBORCA_CompileEntryImport(
            0, 
            ... ,
            128, 
            Marshal.GetFunctionPointerForDelegate(staticCallbackDel), // Delegate to function ptr
            0);

        PBORCA_CompileEntryImport(
            0, 
            ... ,
            128, 
            Marshal.GetFunctionPointerForDelegate(
                new PBORCA_CALLBACK(NonStaticImpOfTheCallback) // create a delegate instance
            ), // Delegate to function ptr
            0);
    }
}

选项2在定义中直接使用delegate

// A template of the function you want other code to call
// Your calling convention may be different
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] // note calling convention
delegate void PBORCA_CALLBACK(IntPtr pDirEntry, IntPtr lpUserData);  

class Orca
{
    [DllImport("LibraryName.dll")]
    private static extern int PBORCA_CompileEntryImport(
        IntPtr hORCASession,
        ...
        long lEntrySyntaxBuffSize,
        [MarshalAs(UnmanagedType.FunctionPtr)] // May or may not be needed
        PBORCA_CALLBACK pCompErrorProc, // note the use of the delegate
        IntPtr pUserData);

    // An implementation of the function delegate (this will be called)
    private static void StaticImpOfTheCallback(IntPtr pDirEntry, IntPtr lpUserData)
    {
        // write code here (Notice: I'm a static function)
    }

    // An implementation of the function delegate (this will be called)
    private static void NonStaticImpOfTheCallback(IntPtr pDirEntry, IntPtr lpUserData)
    {
        // write code here (Notice: I'm a static function)
    }

    // Create a delegate object which will link the callback function
    private PBORCA_CALLBACK staticCallbackDel = StaticImpOfTheCallback; 

    public void SomeCallingFunction()
    {
        PBORCA_CompileEntryImport(
            0, 
            ... ,
            128, 
            staticCallbackDel, // no need to convert the delegate
            0);

        PBORCA_CompileEntryImport(
            0, 
            ... ,
            128, 
            StaticImpOfTheCallback, // could call directly too.
            0);

        PBORCA_CompileEntryImport(
            0, 
            ... ,
            128, 
            NonStaticImpOfTheCallback, // could call directly too.
            0);

        // same as above (I think)
        PBORCA_CompileEntryImport(
            0, 
            ... ,
            128, 
            new PBORCA_CALLBACK(NonStaticImpOfTheCallback), // more explicit
            0);
    }
}

这些是我能想到的大多数变化。其中之一应该适合您。如果以上内容不清楚,我建议您阅读一些文档,了解委托在正常C#中的工作方式,并在尝试将其与C ++代码结合使用之前在其中进行实验。有很多在线教程可供代表使用,如果其中还没有,那么他们中的一员应该希望能得到一分钱。

祝你好运

© www.soinside.com 2019 - 2024. All rights reserved.