当我从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#调用C ++之间存在差异。
我也不知道为什么这只会在Windows 7上发生(两个Windows安装都有.net 3.5 SP1)。
有没有人知道这是什么原因?
此外,如果有人知道可以在Window 7上运行的本机内存分析工具,我很高兴知道(现在我只是打印到控制台所有显式内存分配,并没有差异)。
答案 0 :(得分: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);
评论员的解释:
通常,零或空指针 任何其他值都将值转换为false value转换为true。
...
1998 C ++标准库定义 向量的特化 布尔的模板。的描述 班级表明了 实施应该打包 元素使每个bool只使用 一点记忆。
所以,无论你使用什么值,你都会得到一个值为true或false的c ++布尔值。
答案 1 :(得分:2)
不幸的是,一旦你涉及字符串,没有编组很简单。
我们需要更多数据才能帮助您找到此问题。你能提供以下
吗?修改强>
尝试以下签名。这告诉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);
答案 2 :(得分:1)
我发现在查找内存泄漏时使用CLR Profiler很有帮助。
答案 3 :(得分:0)
您确定存在内存泄漏吗?
确定内存泄漏的基础是什么?你说你可以从性能指标看到它,但你实际观察到了什么?你是否看到一条连续上升的曲线,或者一条稳定在高位的曲线?高内存消耗通常会因内存泄漏而混淆。
顺便说一句。你也可以发布C ++函数定义吗?