Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 willbailey · Jun 09, 2016 at 02:52 PM · audioplugindllpluginsdllimport

nonstatic extern functions from DLL plugin import

Hi

I'm working on an acoustic room simulation with the processing being performed in a dll. It seems as though calling the function via dllimport requires the function to be static, limiting me to one audio source at a time, due to the design of the DSP. Is there a way to create nonstatic instances of imported extern functions so that they can be used as independent objects?

Thanks

Comment
Add comment
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

1 Reply

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

Answer by Bunny83 · Jun 09, 2016 at 06:12 PM

The concept of "instance" method is actually just some sugar that the compiler / framework provides. Actually all methods are static as the code for those methods only exist in one place. Instance method just have an additional, hidden parameter "this". That's usually the first parameter that is passed to the method.

If you want to call a native method for a certain native object, you would need to pass the native object reference along to the method call. Usually you would create a wrapper class in .NET / C# that holds that native pointer (IntPtr) and provides the required method for the C# environment. Those calls are then forwarded to the native interface using static exported methods and just pass the object along.

Unity does something similar for almost everything inside the Untiy API. However they don't pass the native pointer alone but simply the managed object. That's what UnityEngine.Object is for. It contains an IntPtr to the native object. When a native method is called they pass the managed object. From this managed object reference the native code can get the pointer to the native object.

edit

This is not a "full" example and it doesn't necessary need to compile at all. It just should demonstrate the basic concept. First of all you have to think about who is actually creating the native object. If the creation is initiated from managed code (which would be usually the case) you can trigger the native object creation in the constructor of our wrapper class.

 // C#
 public class SomeNativeObject
 {
     private IntPtr m_NativeObject = IntPtr.Zero;
     public SomeNativeObject()
     {
         m_NativeObject = Internal_CreateNativeObject();
     }
     ~SomeNativeObject()
     {
         Destroy();
     }
     public void Destroy()
     {
         if (m_NativeObject != IntPtr.Zero)
         {
             Internal_DestroyNativeObject(m_NativeObject);
             m_NativeObject = IntPtr.Zero;
         }
     }
     public void SomeNativeMethod(int SomeParameter)
     {
         if (m_NativeObject == IntPtr.Zero)
             throw new Exception("No native object");
         Internal_SomeNativeMethod(m_NativeObject, SomeParameter);
     }
     [DllImport("YourDLL")]
     private static extern IntPtr Internal_CreateNativeObject();
     [DllImport("YourDLL")]
     private static extern Internal_DestroyNativeObject(IntPtr obj);
     [DllImport("YourDLL")]
     private static extern void Internal_SomeNativeMethod(IntPtr obj, int SomeParameter);
 }

And this would be the matching C++ code:

 // C++
 extern "C" {
     YourNativeObject* Internal_CreateNativeObject()
     {
         YourNativeObject* obj = new YourNativeObject();
         // you might want to store the object reference on the native side for tracking
         return obj;
     }
     void Internal_DestroyNativeObject(YourNativeObject* obj)
     {
         // may need to update your tracking in native code
         delete obj;
     }
     void Internal_SomeNativeMethod(YourNativeObject* obj, int SomeParameter)
     {
         obj->SomeNativeMethod(SomeParameter);
     }
 }

Here "YourNativeObject" is your C++ class name. As i said no guarantee that this will work exactly that way. The last time i used C++ was about 5 years ago. You might have to adjust the marshalling of the parameters but that's the basic concept.

Unity's internal methods usually pass the managed object which would be marshalled into a native wrapper class. From that they most likely retrieve the actual pointer to the actual native object.

Of course i don't have to mention that you have to be careful when creating and destroying native objects. Also locking / synchronising within multithreaded environments should be carried out carefully.

The C# wrapper class might also implement the IDisposable interface and Destroy the object in Dispose(). You have to think about who owns the native object. At the moment if the C# managed wrapper class get out of extent and is garbage collected the native object is destroyed. If you don't want the managed world to "own" the native object you should remove all those "auto destroy" things and require the constructor to pass in the native object pointer.

Comment
Add comment · Show 4 · 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 willbailey · Jun 10, 2016 at 11:47 AM 0
Share

Thanks for your reply, this is a concept I haven't come across before so forgive me if it seems I'm not grasping it.

Could you explain/demonstrate a trivial example?

avatar image willbailey · Jun 10, 2016 at 12:45 PM 0
Share

Thank you for this, the example is just what I was hoping for. Thank you for taking the time to do this. Very much appreciated!

avatar image elenzil · Jun 10, 2016 at 03:02 PM 1
Share

this should be part of the unity docs!

avatar image willbailey · Jun 14, 2016 at 05:15 PM 0
Share

Wrote this into my code and the layout described here works flawlessly. Thanks again!

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

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do you use a class from a .dll file? 1 Answer

How to link to scripts in the Package Manager when building a dll. 0 Answers

How to properly use my own DLLs in Unity? 2 Answers

EntryPointNotFoundException - .so plugin (Linux) 0 Answers

Dll not found exception: unable to load dll 0 Answers


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