从 C++ 到 C# 的结构中编组回调
Marshal callback in a struct from C++ to C#
我需要 return 关于对象的必要信息,作为具有回调和其他数据的结构。
这是 C# 端的样子:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ChartAddDataCallback(IntPtr data, int size);
[StructLayout(LayoutKind.Sequential)]
public struct ChartAccessors
{
public IntPtr HWnd;
public ChartAddDataCallback addDataCallback;
}
[DllImport("CppPart.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GetAccessors")]
public static extern ChartAccessors GetAccessors();
C++ "mirrored" 版本如下所示:
typedef void(__cdecl *AddDataCallback) (int * data, int size);
struct ChartAccessors
{
HWND m_chartHWnd;
AddDataCallback m_addDataCallback;
};
extern "C" __declspec(dllexport) ChartAccessors GetAccessors();
用法:
static void Main(string[] args)
{
ChartAccessors accessors = GetAccessors();
}
但是,当我启动程序时出现异常 "Method's type signature is not PInvoke compatible."
如果我使用任何其他 return 类型(如 int 或 float)而不是结构,它会起作用。
正如 Pavel 指出的那样,Marshal.PtrToStructure 实际上正在解决这个问题。
void RegisterCallbacks(IntPtr callbackPtr)
{
ChartAccessors accessors = (ChartAccessors)Marshal.PtrToStructure(callbackPtr, typeof(ChartAccessors));
// do stuff with the struct
}
我需要 return 关于对象的必要信息,作为具有回调和其他数据的结构。
这是 C# 端的样子:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ChartAddDataCallback(IntPtr data, int size);
[StructLayout(LayoutKind.Sequential)]
public struct ChartAccessors
{
public IntPtr HWnd;
public ChartAddDataCallback addDataCallback;
}
[DllImport("CppPart.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GetAccessors")]
public static extern ChartAccessors GetAccessors();
C++ "mirrored" 版本如下所示:
typedef void(__cdecl *AddDataCallback) (int * data, int size);
struct ChartAccessors
{
HWND m_chartHWnd;
AddDataCallback m_addDataCallback;
};
extern "C" __declspec(dllexport) ChartAccessors GetAccessors();
用法:
static void Main(string[] args)
{
ChartAccessors accessors = GetAccessors();
}
但是,当我启动程序时出现异常 "Method's type signature is not PInvoke compatible."
如果我使用任何其他 return 类型(如 int 或 float)而不是结构,它会起作用。
Marshal.PtrToStructure 实际上正在解决这个问题。
void RegisterCallbacks(IntPtr callbackPtr)
{
ChartAccessors accessors = (ChartAccessors)Marshal.PtrToStructure(callbackPtr, typeof(ChartAccessors));
// do stuff with the struct
}