If you’ve followed any of my earlier blog posts, you know that I tend to explore areas like NFC and Bluetooth Low Energy from a BlackBerry 10 developer’s perspective – usually in conjunction with my colleague Martin Woolley .
So you may be wondering why I’m writing about Unity 3D today. Well, if you weren’t already aware, Unity 3D is a phenomenal framework that allows you to develop amazing games on multiple platforms, including BlackBerry 10. What’s more, it contains a very flexible plugin framework that allows you to extend your game’s capabilities down into native capabilities of BlackBerry 10!
So naturally, I wondered if I could add the capability to a Unity 3D game to interact with, say, a Bluetooth Smart device. Imagine influencing gameplay through data streamed from a Heart Rate Monitor worn by the player. (Hold that thought for a bit!)
Because I already know how to interact with Bluetooth Smart devices, it’s just a case of embedding the Bluetooth functionality in a native shared library and plugging it into the Unity 3D framework. I’ll share how to do just that in future blog post.
However, today I’d like to share with you what, as a Unity 3D newbie, I had to do to get to the root-cause of a particularly opaque error I encountered when testing my plugin in and application on a BlackBerry 10 device. I kept on seeing “DllImportException” errors, which suggested that my plugin couldn’t be found by the running application.
Background on Unity 3D Plugins Unity 3D plugins are basically shared libraries. For example, libBtHrmPlugin.so (my embryonic Bluetooth Low Energy Heart Rate Monitor Plugin) exposes a set of “C” functions something like this:
<img data-attachment-id="17314" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_1/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_1.jpg" data-orig-size="411,173" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_1" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_1.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_1.jpg?w=411" class="aligncenter size-full wp-image-17314" alt="Diary of a 3D Newbie_1" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_1.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_1.jpg 411w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_1.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_1.jpg?w=300 300w" sizes="(max-width: 411px) 100vw, 411px" />
Unity 3D applications typically use C# (using the cross-platform Mono Framework) or JavaScript to express game logic, and to link these external function references into your Unity 3D script you would typically, in the case of C#, use the statements like the ones below. The directive DllImport has a peculiar name because C# originated on Windows and a DLL is a Dynamic Link Library (the Windows analogue to a shared library on BlackBerry 10). Notice that the name of the library to import is “BtHrmPlugin ” rather than “libBtHrmPlugin.so ”. Mono will try a variety of permutations of names as it tries to locate the underlying library and this gives an element of platform independence to naming of the plugin libraries.
<img data-attachment-id="17315" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_2/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_2.jpg" data-orig-size="607,195" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_2" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_2.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_2.jpg?w=607" class="aligncenter size-full wp-image-17315" alt="Diary of a 3D Newbie_2" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_2.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_2.jpg 607w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_2.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_2.jpg?w=300 300w" sizes="(max-width: 607px) 100vw, 607px" />
So, all is looking good and we run the application on the BlackBerry 10 device:
<img data-attachment-id="17316" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_3/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_3.jpg" data-orig-size="600,201" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_3" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_3.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_3.jpg?w=600" class="aligncenter size-full wp-image-17316" alt="Diary of a 3D Newbie_3" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_3.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_3.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_3.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_3.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
Whoops! Bang! Something went wrong and we see a DllImportException when we look at the log file:
<img data-attachment-id="17317" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_4/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_4.jpg" data-orig-size="600,80" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_4" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_4.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_4.jpg?w=600" class="aligncenter size-full wp-image-17317" alt="Diary of a 3D Newbie_4" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_4.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_4.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_4.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_4.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
How annoying! So, how do you deal with this issue? Here’s what I’ve found to be a logical set of steps that I’ll outline below:
Ensure that the plugin is added to the correct path in the Unity 3D project. Switch on Mono debugging via the bar-descriptor.xml file to understand what actual file names Mono is attempting to use to locate the shared library. Switch on QNX dynamic library logging to understand how the underlying dlopen() service is searching for the shared library. Ensure that the plugin is in the correct path in the Unity 3D project This may seem obvious but it caught me out. Your plugin (libBtHrmPlugin.so in my case) needs to go here in your Unity 3D project’s Assets folder. It won’t be included in the project’s “.bar” file as an asset unless it goes here:
<img data-attachment-id="17318" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_5/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_5.jpg" data-orig-size="490,276" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_5" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_5.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_5.jpg?w=490" class="aligncenter size-full wp-image-17318" alt="Diary of a 3D Newbie_5" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_5.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_5.jpg 490w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_5.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_5.jpg?w=300 300w" sizes="(max-width: 490px) 100vw, 490px" />
As a sanity check, you can check the “.bar” file, which you can find here:
<img data-attachment-id="17319" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_6/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_6.jpg" data-orig-size="600,337" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_6" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_6.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_6.jpg?w=600" class="aligncenter size-full wp-image-17319" alt="Diary of a 3D Newbie_6" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_6.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_6.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_6.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_6.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
Open the “.bar” file with a tool like “7-zip ” and there it is in the “nativelib ” folder. So, we verified that the plugin has been included in the “.bar” file as an asset and it will be installed onto the device as party of the application.
<img data-attachment-id="17320" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_7/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_7.jpg" data-orig-size="600,229" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_7" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_7.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_7.jpg?w=600" class="aligncenter size-full wp-image-17320" alt="Diary of a 3D Newbie_7" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_7.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_7.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_7.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_7.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
Check to see where Mono is looking for the file on the device When Unity 3D builds a project for BlackBerry 10, it assembles all the project assets in a “StagingArea ” folder. Here is where it’s located:
<img data-attachment-id="17321" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_8/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_8.jpg" data-orig-size="600,268" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_8" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_8.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_8.jpg?w=600" class="aligncenter size-full wp-image-17321" alt="Diary of a 3D Newbie_8" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_8.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_8.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_8.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_8.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
We’re interested in the “bar-descriptor.xml ” file that is created by Unity 3D. The part of this file that is of interest to us is the following:
<img data-attachment-id="17322" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_9/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_9.jpg" data-orig-size="600,70" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_9" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_9.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_9.jpg?w=600" class="aligncenter size-full wp-image-17322" alt="Diary of a 3D Newbie_9" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_9.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_9.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_9.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_9.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
Here, the environment variable LD_LIBRARY_PATH , which determines the search location for shared libraries at run-time for BlackBerry 10 applications, is correctly set to include the “native/lib” path. If we add the following line to the “ bar-descriptor.xml”, this will switch on additional logging when Mono tries to locate the shared library at run-time:
<img data-attachment-id="17323" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_10/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_10.jpg" data-orig-size="600,85" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_10" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_10.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_10.jpg?w=600" class="aligncenter size-full wp-image-17323" alt="Diary of a 3D Newbie_10" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_10.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_10.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_10.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_10.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
Then we need to rebuild the “.bar” file using the command line something like this, using “BlackBerry-nativepackager.bat”, since Unity 3D would just re-create the “bar-descriptor.xml” file if you used the Unity 3D IDE to rebuild the project. Notice we were careful to delete the old “.bar” file since we didn’t want it included in the new one.
<img data-attachment-id="17324" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_11/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_11.jpg" data-orig-size="600,426" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_11" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_11.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_11.jpg?w=600" class="aligncenter size-full wp-image-17324" alt="Diary of a 3D Newbie_11" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_11.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_11.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_11.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_11.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
If we install this on the device, again using, say, the “blackberry-deploy.bat” command line tool, we can look at the log once again. This time we see something like the following:
<img data-attachment-id="17325" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_12/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_12.jpg" data-orig-size="600,296" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_12" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_12.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_12.jpg?w=600" class="aligncenter size-full wp-image-17325" alt="Diary of a 3D Newbie_12" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_12.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_12.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_12.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_12.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
What we see now is that Mono is reporting on the various permutations of names that it is attempting to use from the base name of “BtHrmPlugin” to locate the underlying shared library file. Perhaps this is able to shed some light on why we’re seeing a problem? If not, then maybe the next step will help.
Switch on QNX dynamic library logging to see what QNX thinks is happening We follow exactly the same process as in the previous section but add two additional statements, which are described in the QNX documentation for “dlopen()” , to the “bar-descriptor.xml” file, thus:
<img data-attachment-id="17326" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_13/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_13.jpg" data-orig-size="600,121" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_13" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_13.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_13.jpg?w=600" class="aligncenter size-full wp-image-17326" alt="Diary of a 3D Newbie_13" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_13.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_13.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_13.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_13.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
When we look at the log file this time, we see a lot of information regarding how the search for the unresolved external references is taking place. We see that the “libBtHrmPlugin.so” shared library is being located correctly in the “native/lib” folder in the application.
<img data-attachment-id="17327" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_14/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_14.jpg" data-orig-size="600,237" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_14" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_14.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_14.jpg?w=600" class="aligncenter size-full wp-image-17327" alt="Diary of a 3D Newbie_14" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_14.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_14.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_14.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_14.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
If we were to look in more detail, we’d see that the issue was not that the shared library was not found, but rather, there were unresolved external references in the shared library itself, which give rise to the “DllImportException” being reported. The real problem was back in the plugin NDK project itself:
<img data-attachment-id="17328" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_15/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_15.jpg" data-orig-size="600,343" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_15" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_15.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_15.jpg?w=600" class="aligncenter size-full wp-image-17328" alt="Diary of a 3D Newbie_15" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_15.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_15.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_15.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_15.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
The reference to the external library “libbtapi.so” (Bluetooth API library) was missing from the project’s link step! Remember that we’re building a shared library, and missing external references are quite legitimate at build-time since they would be resolved at run-time, but we still need to identify the external library to the linker when the project is built.
Adding this fixed the problem:
<img data-attachment-id="17329" data-permalink="http://devblog.blackberry.com/2014/01/diary-of-a-unity-3d-newbie-solving-dllimportexception-errors/diary-of-a-3d-newbie_16/" data-orig-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_16.jpg" data-orig-size="600,318" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":""}" data-image-title="Diary of a 3D Newbie_16" data-image-description="" data-medium-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_16.jpg?w=300" data-large-file="/content/dam/devblog-blackberry-com/images/blogs/2014/01/diary-of-a-3d-newbie_16.jpg?w=600" class="aligncenter size-full wp-image-17329" alt="Diary of a 3D Newbie_16" src="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_16.jpg?w=800" srcset="http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_16.jpg 600w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_16.jpg?w=150 150w, http://rimdevblog.files.wordpress.com/2014/01/diary-of-a-3d-newbie_16.jpg?w=300 300w" sizes="(max-width: 600px) 100vw, 600px" />
Summary I hope that my own experience has given you some insight into how to logically track down this sort of issue in any Unity 3D plugin you may write, and how it could be used in a more general context to find the root cause of unresolved references in your application.
I’ll be following up this post with one on the Unity 3D Bluetooth Low Energy Heart Rate Monitor plugin I’m currently writing, so watch this space!
Additional Resources If you want to know more about Bluetooth Low Energy, then look here at the index of material produced by John Murray and Martin Woolley.