我声明了以下结构(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" };
}
我的期望是ReturnFailureWithMessage
通过P / Invoke从C#调用(一种测试方法,如果您想知道的话)。在NativeOperationResult
构造函数中,它获取“ Test”的副本并将其放入中ErrorMessage
。
NativeOperationResult具有的所有权,char16_t*
因此在销毁该结构时,我需要将其删除。没问题,但是我不想在.NET CLR有机会将字符串复制到托管堆之前删除内存。
坦白说,我对删除该内存的位置有点模糊。我认为C ++编译器将复制我的struct(或直接移动它),然后CLR将使用该副本...这意味着我应该使用删除.NET中的本机内存Marshal.FreeHGlobal
。
那是对的吗?
不,那是不正确的。您需要区分两种情况:
1)您没有在C ++方面进行任何分配。您现在正在谈论的就是这种情况。
2)您确实在C ++方面进行了分配,因此需要注意释放。
因此可以回答您的问题:不,您的示例不需要任何“删除”内存,因为没有人明确分配内存。
第二种情况比较棘手。如果使用C ++进行内存分配new char16_t[blah]
,则需要使用释放内存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 */
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句