Search Unity

Having trouble making a native OS X plugin

Discussion in 'macOS' started by Tony-Lovell, May 3, 2016.

  1. Tony-Lovell

    Tony-Lovell

    Joined:
    Jul 14, 2014
    Posts:
    127
    I have ten or so 32-bit dylibs that I'd like to put into a plug-in, for use by a 32-bit OS X Unity player. There ARE no 64-bit versions of these dylibs, and so I am content for the moment to not support 64 bit mode.

    I am having trouble getting calls into even one of these dylibs to work, and so I have some questions.

    1. The docs ambiguously state that for OS X "you should build your plugin as a universal binary that contains both 32-bit and 64-bit architectures" (I added the bold). Do they mean I must, or just that this is a good practice?

    2. In my C# code for MyPlugin.bundle containing libMyLib.dylib, should the string constant in the DllImport() attribute be "MyPlugIn" or "MyLib" for a function that resides within the libMyLib.dylib library? I suspect the former, based on my results, even though this seems a poor design choice, as a Windows version of this plugin will require different attributes to work.

    Though I have my dylibs ready to go, I'm trying an incremental approach to learn the ropes. If I strip my bundle down to the simplest case where there is just one 32-bit dylib within it, which has no external dependencies, I find I am still not succeeding.

    If I run "otool -L libMyLib.dylib", I get

    Code (csharp):
    1. libMyLib.dylib:
    2.     @loader_path//libMyLib.dylib (compatibility version 0.0.0, current version 0.0.0)
    3.     /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
    4.     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
    However, if I call a single function within the dylib which has the attribute [DllImport("MyPlugin", CallingConvention = CallingConvention.Cdecl)], I get

    Code (csharp):
    1. Couldn't open MyApp.app/Contents/Plugins/MyPlugin.bundle/Contents/MacOS/MyPlugin, error: dlopen(MyApp.app/Contents/Plugins/MyPlugin.bundle/Contents/MacOS/MyPlugin, 2): library not loaded: @rpath/libMyLib.dylib
    2. referenced from: MyApp.app/Contents/Plugins/MyPlugin.bundle/Contents/MacOS/MyPlugin
    3. reason: image not found
    4. Couldn't open MyApp.app/Contents/Plugins/MyPlugin.bundle/Contents/MacOS/MyPlugin, error: dlopen(MyApp.app/Contents/Plugins/MyPlugin.bundle/Contents/MacOS/MyPlugin, 2): library not loaded: @rpath/libMyLib.dylib
    5. referenced from: MyApp.app/Contents/Plugins/MyPlugin.bundle/Contents/MacOS/MyPlugin
    6. reason: image not found
    7. DllNotFoundException: MyApp.app/Contents/Plugins/MyPlugin.bundle/Contents/MacOS/MyPlugin
    8.  
    I would really love to hear from anyone with some experience in this.

    Thanks in advance!

    tone
     
  2. Nabren

    Nabren

    Joined:
    Mar 7, 2014
    Posts:
    61
    1) While it's a good idea to build fat binaries with x86 and x86_64 if you are worried about maximum compatibility, most Applications on OS X these days only support x86_64. So I would actually recommend only building for x86_64 if you can track down 64-bit versions of the dynamic libraries you are using.

    2) The DllImport attribute is meant to specify the DLL containing the extern, see https://msdn.microsoft.com/en-us/li...eropservices.dllimportattribute(v=vs.90).aspx

    For cross-platform development, it's actually suggested to omit the .dll extension as it will automatically try to resolve using platform dependent extensions in Mono in addition to .dll (.a for iOS/Mac, .so for Android, etc...). Just make sure you are specifying the file on disk that contains the extern symbol. In your case you are having to specify MyPlugin because that is the built assembly that references "MyLib".
     
  3. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    SachinGanesh likes this.