当我从 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#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);

的评注的解释:

对于C ++ bool类型:

  

在一般情况下,零或空指针   值被转换为假,任何其他   值被转换为真实的。

...结果

  

在1998年C ++标准库定义   载体的专业化   模板布尔。的说明   该类指示   实现应该收拾   元素使每一位BOOL仅使用   的存储器中的一个位。

所以,几乎无论您使用的价值,你会得到一个值为C ++的布尔真或假。

其他提示

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

我们需要更多的数据以帮助追踪这一问题。你可以提供以下

  • 地方签名
  • 是怎样的记忆字符串的管理,在本机代码吗?
  • 也许C++的样本里你使用API?

编辑

试试下面签名。这告诉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 分析器 当发现我的内存泄漏时很有帮助。

您肯定有内存泄漏?

你是什么,用于确定内存泄漏基础。你说,你可以从性能计数器看到它,但你是什么实际观察到?你看到的是一个高层次平息一个coninously上升的曲线,或者一个?高存储器消耗经常被混淆了内存泄漏。

顺便说一句。你可以发布你的C ++函数定义呢?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top