3

我正在编写一个供本机 C++ 应用程序使用的 C# 库。我使用 C++/CLI 作为互操作性机制。

我需要将回调函数从 C++ 传递到 C#(使用 C++/CLI 作为中间层)。C# 库需要使用以零结尾的宽字符字符串调用 C++ 函数;即回调函数的原型是

函数(LPCWSTR pszString);

还有其他参数,但它们对于本次讨论无关紧要。

我在网上搜索并找到了我可以使用的 Marshal.GetDelegateForFunctionPointer 方法。问题在于它将 System.String 从 C# 转换为 char* 而不是我正在寻找的 wchar_t*。

此外,如果可能的话,实现此代码示例的最佳方法是什么,包括 C++/CLI 部分。C++/CLI dll 依赖于 C# dll。方法需要同步调用。

4

2 回答 2

8

GetDelegateForFunctionPointer可以,但是您需要[MarshalAs(UnmanagedType.LPWStr)]在委托声明中为参数添加一个属性,以便String转换为wchar_t*

delegate void MyDelegate([MarshalAs(UnmanagedType.LPWStr)] string foo)

IntPtr func = ...;
MyDelegate del = (MyDelegate)Marshal.GetDelegateForFunctionPointer(func,
                                 typeof(MyDelegate));

要传递可修改的字符串,请给出StringBuilder. 您需要为非托管函数显式保留空间以使用:

delegate void MyDelegate([MarshalAs(UnmanagedType.LPWStr)] StringBuilder foo)

StringBuilder sb = new StringBuilder(64); // reserve 64 characters.

del(sb);
于 2011-06-08T16:52:48.190 回答
2

如果您想使用或诸如此类,请参阅鲜为人知的UnmanagedFunctionPointer属性,就像代表一样。DllImportCharSet

于 2011-07-22T03:59:50.040 回答