从Windows 7中的托管代码调用非托管代码时出现内存泄漏

Mei*_*lon 7 c# c++ memory-leaks windows-7 vshost.exe

当我从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);
Run Code Online (Sandbox Code Playgroud)

和原生的:

MyDll_Export bool APIENTRY MyMethod(
int x,
const wchar_t*  y, 
const wchar_t*  z,
bool v,
bool w)
Run Code Online (Sandbox Code Playgroud)

当我从C++调用它时,我称之为:

MyMethod(1, L"My String 1", L"My String 2", true, true)
Run Code Online (Sandbox Code Playgroud)

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

有谁知道这是什么原因?

此外,如果有人知道一个适用于Window 7的本机内存分析工具,我很高兴知道(现在我只是打印到控制台所有显式内存分配,没有差异).

sco*_*ttm 5

我确信这个问题与将C#数据类型编组到他们的C++计数器部分有关.由于您将返回值bool编组为有符号的1字节值,您可能应该对函数参数执行相同的操作吗?C#bool类型是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);
Run Code Online (Sandbox Code Playgroud)

评论员的解释:

对于C++ bool类型:

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

...

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

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