在Windows 7中从托管代码调用非托管代码时发生内存泄漏

当我从C#代码中调用一个非托管的C ++代码时,我似乎有某种内存泄漏。
C ++使用ifstream.read从文件读取数据,并将其写入Vector。

这只会在升级到Windows 7之后才会发生,在Vista上不会发生,但如果我使用在Vista上编译的原生dll版本,它不会改变任何内容!
如果我直接运行相同的C ++代码,而没有托管互操作,则不存在内存泄漏!
如果我运行托管进程,但在vshost进程中,则不会发生内存泄漏!

这是呼叫签名:

        [DllImport(DllPath, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern bool MyMethod(
        int x, 
        string  y, 
        string  z, 
        bool    v, 
        bool    w);

和原生的一个:

MyDll_Export bool APIENTRY MyMethod(
int x,
const wchar_t*  y, 
const wchar_t*  z,
bool v,
bool w)

当我用C ++调用它时,我这样称呼它:

MyMethod(1, L"My String 1", L"My String 2", true, true)

当我查看托管和非托管内存的性能计数器时,我发现所有内存都来自非托管代码。
考虑到编组非常简单,我不明白为什么直接调用C ++或通过C#有区别。
我也不知道为什么只有在Windows 7上才会发生这种情况(两个Windows安装都有.net 3.5 SP1)。

有没有人有一个想法是什么原因呢?

另外如果有人知道在Window 7上工作的本地内存分析工具,我会很高兴知道(现在我已经打印了控制所有显式内存分配并且没有区别)。


我确信这个问题与把C#数据类型编组到C ++计数器部分有关。 既然你将返回值布尔编组为一个有符号的1字节值,也许你应该对函数参数做同样的事情? C#布尔类型是4个字节,也许你在那里泄漏?

此外,指定字符串的非托管类型可能会有所帮助。

[DllImport(DllPath, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool MyMethod(
        int x,
        [MarshalAs(UnmanagedType.LPWStr)]
        [In] string y,
        [MarshalAs(UnmanagedType.LPWStr)]
        [In] string z,
        [MarshalAs(UnmanagedType.I1)]
        bool v,
        [MarshalAs(UnmanagedType.I1)]
        bool w);

对评论者的解释:

对于C ++ bool类型:

通常,将零或空指针值转换为false,将其他任何值转换为true。

...

1998年的C ++标准库为bool定义了矢量模板的专门化。 类的描述表明实现应该打包元素,以便每个bool只使用一位内存。

所以,无论你使用什么值,你都会得到一个值为true或false的c ++布尔值。


不幸的是,一旦你涉及字符串,没有编组很简单。

我们需要更多的数据来帮助您追踪这个问题。 你能提供以下几点

  • 原生方法签名
  • 本机代码中的字符串内存是如何管理的?
  • 也许你使用API​​的C ++示例?
  • 编辑

    尝试以下签名。 这告诉CLR不要在两个方向编组内存,而只是传入数据。

        [DllImport(DllPath, CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.I1)]
        public static extern bool MyMethod(
                int x, 
                [In] string  y, 
                [In] string  z, 
                bool    v, 
                bool    w);
    

    当发现我的内存泄漏时,我发现CLR Profiler的使用很有帮助。

    链接地址: http://www.djcxy.com/p/57033.html

    上一篇: memory leak when calling unmanaged code from managed code in Windows 7

    下一篇: What strategies and tools are useful for finding memory leaks in .NET?