我想将功能从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);
据我了解,有几种可能的方法。这将取决于您的要求。
选项1)使用IntPtr
和Marshal.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 ++代码结合使用之前在其中进行实验。有很多在线教程可供代表使用,如果其中还没有,那么他们中的一员应该希望能得到一分钱。
祝你好运