- Home /
Creating an instance of a C++ plugin
We have a C++ library that we want to use to build a Unity plugin.
Looking at the documentation and various tutorials they all seem to call static functions from libraries but do not create instances of the libraries (i.e. MyClass a = new MyClass() ). I seem to get errors trying to create a c# script that makes a call like this.
Our library stores persistant data once instantiated so cannot really be used in a "functional" programming style.
Is there a standard way of creating instances of plugin classes within a C# script?
Just added a sample to my answer. It's a singleton manager to manage instances of a special class (SomeClass) in c++ but controlled by unity (C#).
Thats awesome, the code below should be a great resource for anyone trying to do the same thing, now I will add a singleton factory to our library (always useful anyway) and see how that goes.
How did it work? We're also trying to use a C++ class in a Unity plugin, and so far it's been frustrating. Like you said, functions work great, but classes are not documented. Did you end up finding a way? I realize this topic is over a year old, but I'm hoping you still remember.
Answer by Bunny83 · Feb 24, 2011 at 08:14 PM
Well, a class in c++ consists of the actual data fields (+vtable at the beginning). C# classes works totally different since every class is inherited from Object.
You can not (at least I don't know a way) simply use a c++ class in C#. But you can use stdcalls.
Actually i've never tried something like that, but i've found this article that might help:
http://blogs.msdn.com/b/vcblog/archive/2008/12/08/inheriting-from-a-native-c-class-in-c.aspx
In the end it's always a lot of work to merge managed code and native code.
Here's the Unity documentation page about plugins:
http://unity3d.com/support/documentation/Manual/Plugins.html
As the documentation says you can "call into native code libraries" but to use a whole class is not that easy because the underlaying systems are too different. Maybe someone have a bit more experience on that topic, I'm quite new to C# (about a year) and haven't revealed all features and possibilities yet.
EDIT I just wrote a little example how i would manage the objects in c++. Sure, you could just return the pointer to an instance as int, but i don't want to mix memory management. It's a bit saver that way and you have an easy overview of all objects within c++. I've not tested this dll with unity but it compiles and the exports look fine ;)
// Example.h #include <map>
class CSomeClass { public: CSomeClass() { }; void MyFunction(int aParam1) { }; };
class CManager { private: CManager() { }; ~CManager() { }; static CManager* m_Instance; public: static CManager* Get() { if (!m_Instance) m_Instance = new CManager(); return m_Instance; } static void Destroy() { if (m_Instance) delete m_Instance; m_Instance = NULL; } public: int CreateSomeClass() { m_Objects[m_NextID] = new CSomeClass(); return m_NextID++; } CSomeClass* GetSomeClass(int aID) { if (m_Objects.find(aID) == m_Objects.end()) return NULL; return m_Objects[aID]; } void DeleteSomeClass(int aID) { std::map<int,CSomeClass*>::iterator it = m_Objects.find(aID); if (it == m_Objects.end()) return; delete it->second; m_Objects.erase(it); } private: int m_NextID; std::map<int,CSomeClass*> m_Objects; };
//Well and here's the cpp: // Example.cpp CManager* CManager::m_Instance = NULL;
define EXPORT_API __declspec(dllexport)
xtern "C" { EXPORT_API int CreateSomeClass() { return CManager::Get()->CreateSomeClass(); } EXPORT_API void DeleteSomeClass(int aID) { CManager::Get()->DeleteSomeClass(aID); } EXPORT_API void SomeClass_MyFunction(int aID, int aParam1) { CSomeClass* tmp = CManager::Get()->GetSomeClass(aID); if (tmp) tmp->MyFunction(aParam1); } }
//--------------------------------------------- // In Unity you can create a wrapper class like:
public class SomeClass { private int m_CPPClassID = -1; public SomeClass() { m_CPPClassID = CreateSomeClass(); } public ~SomeClass() { DeleteSomeClass(m_CPPClassID); } public void MyFunction(int aParam1) { SomeClass_MyFunction(m_CPPClassID, aParam1); }
[DllImport ("PluginName")]
private static extern int CreateSomeClass();
[DllImport ("PluginName")]
private static extern void DeleteSomeClass(int aID);
[DllImport ("PluginName")]
private static extern void SomeClass_MyFunction(int aID, int aParam1);
}
I just wrote that from scratch so it's not optimised and not all possible error checks implemented but it should be just an example anyway :D
Thanks for the link, I will read through that but on first glance it seems like what I want to do is definitely non standard and perhaps using VS C++/ CLI is an easier way to go?
Well, that sounds like another option but as i said i'm not that familiar with .net. I started to use C# together with unity last year. Still a lot to learn even after 16 years pascal/delphi and 3 years c++.
Answer by _Petroz · Feb 24, 2011 at 10:08 PM
Alternatively you could allocate the objects on the C++ side with a static function and just cast to and from IntPtr, that is how the FMOD C# wrapper operates.
Yeah, basically that's always the easiest way to interact. If the class stick close to oop, everything should be an interface ;) wrap the getter and setters in some functions. If you need to create more than one instance you can use a std::map to manage them and return the int as a handle almost like windows does.
Do you have an example of that technique or a link, that would be very useful to see.
Your answer

Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Can someone help me fix my Javascript for Flickering Light? 6 Answers
Setting Scroll View Width GUILayout 1 Answer
Material doesn't have a color property '_Color' 4 Answers
Android plugins and callbacks on non-scripting threads 1 Answer