使用P/Invoke跨C++/C#边界管理非托管字符串
Managing unmanaged string across C++ / C# boundary with P/Invoke
我声明了以下结构(C++):
struct NativeOperationResult {
const INTEROP_BOOL Success; // INTEROP_BOOL = char
const char16_t* const ErrorMessage;
NativeOperationResult(const NativeOperationResult& c);
/* various constructors, omitted for brevity */
};
现在,我在其他地方有一个导出的函数定义:
extern "C" __declspec(dllexport) NativeOperationResult ReturnFailureWithMessage() {
return { INTEROP_BOOL_FALSE, "Test" };
}
我的期望是通过p/Invoke从C#调用ReturnFailureWithMessage
(如果您想知道的话,这是一个测试方法)。在NativeOperationResult
构造函数中,它获取"Test"的副本并将其放入ErrorMessage
中。
NativeOperationResult拥有char16_t*
的所有权,因此我需要在结构被销毁时将其删除。这没问题,但我不想在.NET CLR有机会将字符串复制到托管堆之前删除内存。
坦率地说,我有点不清楚在哪里删除那段记忆。我认为C++编译器会复制我的结构(或者只是移动它),然后CLR会使用该副本。。。这意味着我应该使用Marshal.FreeHGlobal
从.NET中删除本机内存。
这是正确的吗?
不,这是不正确的您需要区分两种情况:
1) 您没有在C++方面进行任何分配这就是您现在所说的情况。
2) 您确实在C++端进行了分配,您需要处理释放。
因此,为了回答您的问题:不,您的示例不需要任何内存的"删除",因为没有人明确分配内存。
第二种情况有点棘手。如果使用new char16_t[blah]
在C++端进行内存分配,则需要使用delete[] nativeOperationResult.ErrorMessage
释放内存。这在C#端是不可能做到的。可以使用不同的分配器(例如;malloc
、new
)来分配内存,而C#不知道如何处理这些指针。
您需要向NativeOperationResult
添加一个新标志,例如DeletionRequired
,并从非托管端导出新函数:FreeNativeOperationResultIfNeeded(..)
。这里还有更长的讨论。
使用C++strings
可以避免所有这些无意义的操作。它们神奇地工作,不需要删除。
struct NativeOperationResult {
const INTEROP_BOOL Success; // INTEROP_BOOL = char
const string const ErrorMessage;
NativeOperationResult(const NativeOperationResult& c);
/* various constructors, omitted for brevity */
};
您可以将其设为out参数,并期望调用方法向其传递适当数量的内存,而不是返回NativeOperationResult。通过这种方式,.Net可以分配内存,然后在pinvoke完成后进行清理。但是,您必须想办法通知.Net它预计要分配的内存量。
extern"C"__declspec(dllexport)void ReturnFailureWithMessage(NativeOperationResult*结果)
- 当分配一个字符串值并稍后通过分配另一个值进行更改时C++如何管理内存?
- 管理字符串文本的最佳做法
- C++将字符串传递给 C 库以进行内存管理
- 指针的一系列指针:管理不同语言的字符串
- 通过读取文件创建映射<字符串,矢量>时如何管理内存<string>
- 在C 中编程基于字符串的事件管理器
- 如何从内存管理职责中释放std字符串
- 管理C#中返回的字符串指针
- C++字符串管理通过字典匹配转换原始字符串
- 字符串串联和内存管理
- C++中具有字符串键的查找表的内存管理
- 我的字母字符串管理器无法正确保存到文件中
- 使用P/Invoke跨C++/C#边界管理非托管字符串
- 管理单个字符串的内存
- 在WinAPI项目中管理字符串资源的现代方式
- python字符串管理和内存
- c++中的字符串处理和内存管理
- 将字符串数组从c#传递到内存管理
- 字符串管理 C/C++ & 从 txt 文件写入和读取
- CPP中字符串的内存管理问题