【问题标题】:How to free an unmanaged memory that was allocated by marshalling from C# to C++如何释放通过从 C# 编组到 C++ 分配的非托管内存
【发布时间】:2016-09-23 13:36:16
【问题描述】:

C++ 代码调用返回字符串的 C# 方法。我应该如何在 C++ 中释放分配的非托管内存?我应该使用 free() 还是 delete?

C#:

[Guid("52E4971F-E075-41BA-A84F-B6BE8BD66A21")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
public interface ISomeInterface
{
     [return: MarshalAs(UnmanagedType.LPWStr)]
     string SomeMethod([MarshalAs(UnmanagedType.LPWStr)] string text);
}

C++:

class SomeClass
{
    virtual int32_t __stdcall _someMethod(const char16_t *text, char16_t **r) = 0;

    char16_t * someMethod(const char16_t *text)
        {
            char16_t * result;
            _someMethod(text, &result);
            return result; // how to correct release this memory?
        }
}

该解决方案适用于 Windows 和 Linux。

【问题讨论】:

  • 能否请您出示一些/您的代码,以便我们以最好的方式提供帮助?

标签: c# c++ interop marshalling


【解决方案1】:

假设您调用的对象具有这样的 COM 签名:

interface MyObj
{
   HRESULT __stdcall MethodOrProp([out, retval] BSTR* SomeStringReturned);
};

然后,您调用 SysFreeString。

MyObj* pObj;
// ....

BSTR bstr = NULL;
HRESULT hr = pObj->MethodOrProp(&bstr);
if (SUCCEEDED(hr))
{
   // ... do junk with string ...
   SysFreeString(bstr);
}

但是,如果您使用的是 Visual Studio,请不要担心,使用 CComBSTR。它将在其析构函数中为您进行清理。

CComBSTR ccbString = NULL;
HRESULT hr = pObj->MethodOrProp(&ccbString);
if (SUCCEEDED(hr))
{
   // ... do junk with string ...
}
// some time at end of scope, destructor of ccbString will clean it up

【讨论】:

  • 感谢您的回答。我在问题描述中添加了更多详细信息。你能再看一遍吗?
  • 据我了解,我不能将 BSTR 用于非 Windows 系统。我说的对吗?
  • 嗯。是的.... 除了在 Windows 上,您打算在哪里使用 COM?我意识到我是一名 Windows 程序员,除了外围设备之外,我不了解其他平台,但我不知道除了 Microsoft 在 Windows 上的任何严重的应用级 COM 实现......这是他们的技术。跨度>
  • @JoeWillcoxson:COM 指定了一个标准化的 ABI。任何人都可以实现针对相同 ABI 的运行时基础架构。而对于 Mono 项目(我假设它也支持 ComVisible 属性),甚至可能存在非 Windows COM 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 2011-11-09
  • 1970-01-01
  • 2013-02-28
  • 1970-01-01
相关资源
最近更新 更多