Smart pointers in C++ - C# interface

1.4k views Asked by At

I am building C++ interface to be called from C# program (using Dllimport/ dll export). I need to use some pointer during my work. Thus leads me to create an (create_engine) method and (destroy_engine) method. is there a way to use a smart pointers so I do not need the destroy method anymore.

code:

 extern "C" _declspec (dllexport) Engine* create_engine(){
        return new Engine();
    }


    extern "C" _declspec (dllexport) void destroy_engine(Engine* engine){
        if (engine != NULL){
            delete engine;
        }
        engine = NULL;
    }

P.S. the smart pointer will be used from C# so it should stay counting how many references even from the C# part... thanks

1

There are 1 answers

0
Jaka Konda On BEST ANSWER

No you can't do this. Half manual and half automatic memory management just isn't an option.

The nearest think you can do is to wrap C++ class for use by C# and manage memory there with shared_ptr for example. Example is on MSDN (code bellow also taken from there): Wrap Native Class for Use by C#

// wrap_native_class_for_mgd_consumption.cpp
// compile with: /clr /LD
#include <windows.h>
#include <vcclr.h>
#using <System.dll>

using namespace System;

class UnmanagedClass {
public:
   LPCWSTR GetPropertyA() { return 0; }
   void MethodB( LPCWSTR ) {}
};

public ref class ManagedClass {
public:
   // Allocate the native object on the C++ Heap via a constructor
   ManagedClass() : m_Impl( new UnmanagedClass ) {}

   // Deallocate the native object on a destructor
   ~ManagedClass() {
      delete m_Impl;
   }

protected:
   // Deallocate the native object on the finalizer just in case no destructor is called
   !ManagedClass() {
      delete m_Impl;
   }

public:
   property String ^  get_PropertyA {
      String ^ get() {
         return gcnew String( m_Impl->GetPropertyA());
      }
   }

   void MethodB( String ^ theString ) {
      pin_ptr<const WCHAR> str = PtrToStringChars(theString);
      m_Impl->MethodB(str);
   }

private:
   UnmanagedClass * m_Impl;
};