从非托管调用托管库时C ++ / CLI包装memleak
从非托管代码调用托管代码库时出现此错误:
运行时检查失败#2 - 变量“BridgeObj”周围的堆栈已损坏。
我创建的代码是:
托管库:
using System;
namespace My.Name.Space
{
public class Sample
{
public int Request(string xml_input, out string xml_output)
{
xml_output = "Retun string.";
return 0;
}
}
}
包装器C ++ / CLI:
#include "stdafx.h"
#include <msclrauto_gcroot.h>
#using "..linkManagedLib.dll"
using namespace System::Runtime::InteropServices; // Marshal
struct ManagedModul
{
public:
msclr::auto_gcroot<My::Name::Space::Sample^> SampleModul;
};
class __declspec(dllexport) Bridge
{
private:
ManagedModul _private;
public:
Bridge()
{
_private.SampleModul = gcnew My::Name::Space::Sample();
};
~Bridge()
{
}
int Request ( const char * xmlin, char ** xmlout )
{
System::String ^ps;
_private.SampleModul->Request(gcnew System::String(xmlin), ps);
* xmlout = (char*) (Marshal::StringToHGlobalAnsi(ps)).ToPointer();
return 0;
}
};
示例用法:
#include "stdafx.h"
#include <Windows.h>
#pragma comment ( lib, "..linkWrapper.lib" )
class Bridge
{
public:
Bridge();
~Bridge();
int Request ( const char * xmlin, char ** xmlout );
};
int _tmain(int argc, _TCHAR* argv[])
{
Bridge BridgeObj;
char * buffer = NULL;
BridgeObj.Request("aaaaa", & buffer );
LocalFree ( buffer );
return 0;
}
class Bridge
{
public:
Bridge();
~Bridge();
int Request ( const char * xmlin, char ** xmlout );
};
这是一个非常非常糟糕的做法。 您没有使用两个项目中使用的.h文件,而是重新声明了Bridge类。 并且弄错了,你错过了_private成员。 这总是出错。 如果不是那么马上,那么在你修改真实的Bridge类的一年之后。
接下来发生的事情是不可避免的。 真正的类对象比编译器在编译重新声明的类时认为的要大。 所以它不会在堆栈上保留足够的空间来存储对象。 不可避免的是,这将导致堆栈中的另一个变量被打乱,只要真正的类分配_private成员就会被覆盖。
购买微软雪茄在这个诊断中构建,像这样的堆栈损坏通常非常难以诊断。 并使用.h文件来声明Bridge。
链接地址: http://www.djcxy.com/p/59615.html上一篇: C++/CLI wrapper memleak when calling managed lib from unmanaged
下一篇: Including headers from an unmanaged C++ code inside C++/CLI code
