代码之家  ›  专栏  ›  技术社区  ›  DraÅ¡ko

当marshaling CString从C++到C时如何(如果需要的话)释放动态内存?

  •  2
  • DraÅ¡ko  · 技术社区  · 15 年前

    我在c++边上有cSnc++,IntPtr ip在c++边上有包含封送机制的CS值。

    然后,我只需要将需要的字符串作为marshal.ptrtostringansi(IP)就可以了,一切都很好,但我想知道我应该删除,如果应该删除,如何删除IP占用的非托管内存,即CS?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Hans Passant    15 年前

    不能,您不知道非托管代码使用了什么分配器来创建cstring实例。而且,你必须调用cstring析构函数,你不能得到它的地址。

    如果这个cSnpe对象作为C++函数的函数返回值返回,那么您就死在水中了。你的问题不清楚。你会有无法控制的内存泄漏。需要用C++/CLI编写的包装器来解决这个问题。作为函数返回值返回的字符串必须由cotaskmemalloc()分配,才能由p/invoke封送拆收器正确清理。没有C++代码可以做到这一点。

        2
  •  1
  •   Darin Dimitrov    15 年前

    非托管代码分配的非托管内存只能由非托管代码释放。因此,您需要添加另一个非托管函数,该函数将获取指向已分配字符串的指针并释放内存。在处理完字符串之后,应该从托管代码调用此函数。

    例子:

    class Program
    {
        [DllImport("test.dll")]
        static extern IntPtr GetString();
    
        [DllImport("test.dll")]
        static extern IntPtr FreeString(IntPtr ptr);
    
        static void Main()
        {
            IntPtr ptr = GetString();
            try
            {
                var str = Marshal.PtrToStringAnsi(ptr);
                // work with the string
            } 
            finally 
            {
                if (ptr != IntPtr.Zero)
                {
                    FreeString(ptr);
                }
            }
        }
    }