C++/CLI wrapper memleak when calling managed lib from unmanaged

I have this error when calling managed code library from unmanaged code:
Run-Time Check Failure #2 - Stack around the variable 'BridgeObj' was corrupted.

The code I created is:

Managed lib:

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;
        }
    }
}

Wrapper 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;
    }
};

Sample usage:

#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 );
};

This is a very, very bad practice. Instead of using a .h file that is used in both projects, you redeclared the Bridge class. And got it wrong, you missed the _private member. This always goes wrong. If not immediately then in a year from now when you modify the real Bridge class.

What happens next is pretty inevitable. The real class object is larger than what the compiler thinks when it compiles your redeclared class. So it doesn't reserve enough space on the stack to store the object. Inevitable, that will cause another variable on the stack to get whacked, overwritten whenever the real class assigns the _private member.

Buy Microsoft a cigar for building in this diagnostic, stack corruption like this is normally extraordinarily hard to diagnose. And use a .h file to declare Bridge.

链接地址: http://www.djcxy.com/p/59616.html

上一篇: 如何在C ++ / CLI代码中引入HWND?

下一篇: 从非托管调用托管库时C ++ / CLI包装memleak