CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11

Threaded View

  1. #7
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Memory leaks when mixing managed & native code

    Nice to see you got it working! Yet I did some more experiments regarding this subject (even after reding post #6).

    My goal was to conceal all the nasty details from my last proposal from the client code and also minimize the native library code changes required. For this purpose I wrote a managed wrapper around your native library, which is quite common practice in such a scenario. The wrapper is a managed (or rather mixed-mode) DLL project which staticaly links in your native library code. More precisely, the wrapper does not link against your .lib file; instead it incorporates the very same (no copies to simplify maintainance) source files of your original library in its project. Preprocessor conditionals take care of the few differences between pure native an mixed-mode compilation. The main thing they do by now is just putting the native library code into its own namespace instead of the global one in the managed wrapper. It's simplest to define BEHIND_MANAGED_WRAPPER project-wide in the ManagedWrapper project settings.

    While doing stepwise refinement of the project, I realized to my surprise that registering an onexit function to clean up the smart pointer isn't even necessary anymore. I'm not entirely sure about the mechanisms responsible for that, but I think it simply is the fact that the native library code now is compiled and linked as part of a mixed-mode project. Not even the forced symbol reference you mentioned in the initial post is required anymore.

    Here are the relevant (parts of the) source files, and I've also attached the updated solution to the post:

    Code:
    // NativeLib.h
    
    #pragma once
    
    #include "stdafx.h"
    
    #include <memory>
    
    #ifdef BEHIND_MANAGED_WRAPPER
    #pragma managed(push, off)
    
    namespace NativeLib
    {
    #endif
    
    class Leak
    {
    };
    
    class Any
    {
      static std::shared_ptr<Leak> var;
    
    public:
        Any();
        ~Any();
    };
    
    #ifdef BEHIND_MANAGED_WRAPPER
    }  // namespace ManagedLib
    
    #pragma managed(pop)
    #endif
    Code:
    // NativeLib.cpp
    
    #include "stdafx.h"
    
    #include "NativeLib.h"
    
    #ifdef BEHIND_MANAGED_WRAPPER
    #pragma unmanaged  // Or explicitly disable CLR support for this module in project settings
    
    using namespace NativeLib;
    #endif
    
    #ifdef _DEBUG
        #define new DEBUG_CLIENTBLOCK
    #endif
    
    // #define NO_LEAK // Comment to omit automatic destruction of statics
    
    std::shared_ptr<Leak> Any::var;
    
    Any::Any()
    {
        var.reset( new Leak );
    }
    
    Any::~Any()
    {
    #ifdef NO_LEAK
        var.reset();
    #endif
    }
    Code:
    // ManagedWrapper.h
    
    #pragma once
    
    #include "../NativeLib/NativeLib/NativeLib.h"
    
    namespace ManagedWrapper
    {
    
    public ref class Any
    {
    public:
      Any() : m_pNativeAny(new NativeLib::Any)
      {}
    
      ~Any()
      {
        delete m_pNativeAny;
      }
    
    private:
      NativeLib::Any *m_pNativeAny;
    };
    
    }
    And finally:

    Code:
    // Form1.h
    
    // ...
    
        public ref class Form1 : public System::Windows::Forms::Form
        {
            ManagedWrapper::Any ^any;
    
        public:
            Form1(void)
            {
                InitializeComponent();
                any = gcnew ManagedWrapper::Any();
            }
    
            // ...
    
        };
    No more low-level fiddling necessary at all!
    Attached Files Attached Files
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured