Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by Ian Wilson · Feb 24, 2011 at 07:13 PM · plugin

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?

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Feb 25, 2011 at 01:00 AM 0
Share

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#).

avatar image Ian Wilson · Feb 25, 2011 at 09:49 AM 0
Share

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.

avatar image ActionScripter · Jun 21, 2012 at 04:57 PM 0
Share

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.

2 Replies

· Add your reply
  • Sort: 
avatar image
5
Best Answer

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

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ian Wilson · Feb 24, 2011 at 09:32 PM 1
Share

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?

avatar image Bunny83 · Feb 24, 2011 at 11:00 PM 0
Share

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++.

avatar image
2

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.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Feb 24, 2011 at 10:50 PM 0
Share

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.

avatar image Ian Wilson · Feb 24, 2011 at 10:57 PM 0
Share

Do you have an example of that technique or a link, that would be very useful to see.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

1 Person is following this question.

avatar image

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


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges