【问题标题】:Marshal callback in a struct from C++ to C#从 C++ 到 C# 的结构中的 Marshal 回调
【发布时间】:2019-02-26 08:38:03
【问题描述】:

我需要将有关对象的必要信息作为带有回调和其他数据的结构返回。

这就是它在 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++“镜像”版本如下所示:

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();
}

但是,当我启动程序时,我收到异常“方法的类型签名与 PInvoke 不兼容。”
如果我使用任何其他返回类型(如 int 或 float)而不是 struct,它就可以工作。

【问题讨论】:

  • 怎么称呼,可以分享一下例子吗?您可以尝试修改GetAccessors(); 方法以返回IntPtr 而不是使用Marshal.PtrToStructure 方法
  • 看看这篇文章docs.microsoft.com/en-us/dotnet/framework/interop/…也许你在C++声明中遗漏了一些东西
  • 嗨,帕维尔,感谢您的回复。我添加了用法(这相当简单)。我试图将它作为 IntPtr 返回并将其编组到结构中,但这给了我一个致命错误。我像这样从 C++ 返回它 -> return new ChartAccessors();
  • 尝试检查这个线程stackoverflow.com/questions/22803083/… charset 和 C/C++ 字符串可能有问题
  • 我的程序中没有字符串

标签: c# c++ struct callback marshalling


【解决方案1】:

Marshal.PtrToStructure 实际上正在解决这个问题,正如Pavel 所指出的那样。

void RegisterCallbacks(IntPtr callbackPtr)
{
    ChartAccessors accessors = (ChartAccessors)Marshal.PtrToStructure(callbackPtr, typeof(ChartAccessors));
    // do stuff with the struct
}

【讨论】:

    猜你喜欢
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多