从非托管调用托管库时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