如何在 C++ 和 C# 之间传递字符串参数
How to pass string parameters between C++ and C#?
我已经在我的 C# 项目中导入了一个C++库。我可以得到一个没有参数的C++方法的答案。我想做的是将一些字符串参数发送到C++并获得它的结果。
在C++:
public String SomeMethod(String param1, String param2)
{
//Some code
}
在 C# 中:
[DllImport("Library Path")]
public static extern string SomeMethod(string param1, string param2);
我该怎么做?
对于从 C# 传递到 C++ 的输入参数字符串,您可以只使用 LPCWSTR
(即 const wchar_t*
C++),并使用 C# 端的 UnmanagedType.LPWstr
选项封送。
但是,当您要将字符串从C++返回到 C# 时,必须注意。
实际上,字符串必须以某种方式在C++中分配,然后字符串指针必须传递给 C#。C# 和 CLR 必须能够在不再需要此字符串时正确释放此字符串,这一点可能会出现问题。例如:C#/CLR 应该能够使用C++代码用于分配字符串的相同分配器释放字符串内存。
对于在 C++ 中创建并在 C# 中使用的字符串使用相同的内存分配器的问题可以使用 BSTR
s 来解决。BSTR
是使用 COM 分配器分配的 COM 字符串,可以使用相同的 COM 分配器释放。因此,C++端和 C# 端可以共享字符串的同一内存分配器。
要返回BSTR
,您可以使用MarshalAs.UnmanagedTypeBStr
选项。
有关 C# 中的字符串封送处理的更多详细信息,请参阅此 MSDN 页面。
C++:
//
// Note: Export using a pure C interface from C++ DLL.
// (You can use C++ *inside* the DLL boundaries.)
// __stdcall is a widely used calling convention for
// C DLL functions (e.g. lots of Win32 APIs use it).
//
extern "C" BSTR __stdcall GetSomeString(void)
{
//
// Note: BSTRs are allocated using SysAllocString()
// (...and freed using SysFreeString()).
//
// You could also use a convenient ATL RAII wrapper
// (instead of using raw BSTRs inside C++ code),
// like CComBSTR.
//
return ::SysAllocString(L"Hello from C++!");
}
在 C# 中:
[DllImport(@"YourDll.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string GetSomeString();
如果选择将 BSTR
s 作为返回的字符串,则为了C++函数接口代码的一致性,您可能还希望使用 BSTR
s 作为输入字符串(即使这不是绝对必要的)。
另一个选项是请求调用方提供一个大小合适的缓冲区,本机C++函数将使用返回的字符串填充该缓冲区。这有点类似于几个 Win32 API(例如 GetWindowText()
) 做。
例如,在这里您可以找到相应的 P/Invoke for GetWindwoText()
:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
但是,我认为从 C# 调用的角度来看,返回BSTR
更好(实际上,例如,在 C# 端,您不需要对输出字符串使用 StringBuilder
等)。
最后但并非最不重要的一点是,您可能感兴趣的另一个选项是构建一个微小的 C++/CLI 桥接层,以将您的本机C++代码公开给 C#,并使用 C++/CLI(例如 System::String
类)在本机和托管之间封送字符串。
- c++ 构造函数 将 1 个字符串参数转换为 3 个属性
- 对函数的 out 字符串参数使用 swap 与赋值
- sscanf() 有两个字符串参数
- isPalindrome不显示输出,isPalindrome函数未使用字符串输入作为字符串参数进行测试
- 如何通过C++在Python函数中传递字符串参数
- 将字符串参数传递给 ifstream
- Pybind11:将字符串*参数传递给构造函数
- 为什么我不能提供一个字符串参数来打印 ncurses?
- 为什么将char*传递给字符串参数会产生汇编错误
- 字符串参数常量字符* 和常量 wchar_t*
- 无法将字符串参数传递到构造函数中?
- 为什么对字符串参数的常量引用可以采用字符串文字?
- C 中的模板专业化中的字符串参数
- 如何使用单声道嵌入将字符串参数传递给 c# 方法
- 如何检查谷歌模拟中作为空指针传递的字符串参数
- 向 const 字符串参数发送 0 int 文本时的访问冲突
- 构造函数字符串参数未设置窗口标题
- C++ 重构采用 int 或字符串参数的方法
- 调用具有字符串参数direct vs variable的函数
- 如何使用 2 个字符串参数从 jni java 库调用