0

I am writing a native plugin for Unity but stuck with lifetime feature of smart pointers.

C#

[DllImport("Serializer")]
private extern static IntPtr Internal_CreateInstance();

somewhere in code:

IntPtr l_nativePtr = Internal_CreateInstance(); //l_nativePtr stay alive forever until i call delete, which is good/acceptable for me.

C++ (My way with raw pointers):

DLL_EXPORT SomeClass* Internal_CreateInstance()
{
   SomeClass* l_obj = new SomeClass();
   return l_obj;
}

The above case was working until i am need for using smart pointers to avoid dangling pointer issue. Actually i need to keep reference of SomeClass in my other class MyArray (which stores in std::listof<SomeClass*>. Somewhere from code if i call delete(SomeClass) instance, then MyArray keeps a pointer which has already been released, then dangling pointer case.

Then i decided to implement smart pointer concept and keeping weak_ptr in MyArray (now std::list<std::weak_ptr<SomeClass>>). But facing below issues.

extern "C"
{
DLL_EXPORT SomeClass* CreateInstance()
{
   std::shared_ptr<SomeClass> l_obj = std::make_shared<SomeClass>(); //LINE#1   
}

Issue#1 (LINE#1): Can't use shared_ptr here because "C" compiler unaware of std:shared_ptr. Solution: Create shared_ptr instance inside 'SomeClass' in a static function and return shared_ptr<SomeClass>.get() for SomeClass* instance. As well as keeping instance of std::shared_ptr<SomeClass> inside SomeClass itself to prevent from auto destroy. Is this good?

Issue#2: If above solution is acceptable, still i can't implement this everywhere in my code. Is there any other way to keep 'std::shared_ptr<>' persistent? I need to use std::weak_ptr to avoid dangling pointer case and std::weak_ptr<> needs std::shared_ptr<> to work with.

Just for info, i am creating pointers in native, returning & keeping reference in C# as IntPtr and whenever i want to perform any operation, i send native_pointer + data e.g.,

C#

[DllImport("Serializer")]
private extern static void Internal_SomeClass_PerformSomething(IntPtr a_nativePtr, bool a_boolValue);

C++

DLL_EXPORT void Internal_SomeClass_PerformSomething(SomeClass* a_nativePtr, bool a_boolValue)
{
...
... //Do things here
}
SatbirSingh
  • 198
  • 1
  • 11
  • Don't use smart pointers in a C++ plugin. Just create a new function that deletes the object in C++. – Programmer Feb 15 '18 at 06:37
  • @Programmer: i was doing the same before smart pointers, but i am stuck with dangling pointer issue. That's why i need 'std::weak_ptr'. – SatbirSingh Feb 15 '18 at 06:47
  • Again, you don't need smart or week pointers. If you have dangling pointer then you are doing something wrong. How are you calling `delete(SomeClass)`? Maybe we can find out why you are having issues in the first place if you post that – Programmer Feb 15 '18 at 07:06
  • Where do you add new instance to the global list? `DLL_EXPORT SomeClass* Internal_CreateInstance()` does not do it in your example. Also, there is no way for native C++ code to know that C# reference to pointer is released and then it should invoke some function. You have to do it explicitly with some "release function" or via some RAII (https://stackoverflow.com/questions/9972763/implementing-raii-in-c-sharp#9972812). No matter how you store your data, you have to tell it C++ to delete – R2RT Feb 15 '18 at 07:34

0 Answers0