Question

I am trying to use some C code in Unity3D pro.

My basic approach is to (1) build C source code into a static libary (2) create an empty bundle and link against the library (3) import the bundle into Unity 3D pro (as a plugin).

I was basically following this tutorial.

It has been working for me for a while until recently when I was updating my C code and recompiling and rebuilding the library and the bundle, everything goes wrong...

When I first imported the bundle, I got a DllNotFoundException.

At that stage my bundle project was merely a pile of libraries - the library built from my source code (which is a .a file) and a few other libraries that I think the .a library depends on (the other libraries have .dylib extension).

I added one test.c file to the bundle. The test .c file contains only two lines:

#include <stdio.h>
#include "ccn.h"

char* say()
{
    return "hi";
}

in which ccn.h is a header file from my C source code.

After I re-built the bundle, the DllNotFoundExeption was gone, but I got an EntryPointNotFoundException.

Here is what I am thinking:

  1. Because Xcode is so intelligent, I am guessing that while was adding the simple test.c file, Xcode modified some of my bundle settings for me. And I believe that's the reason why DllNotFoundException is gone in the first place. Am I thinking right?
  2. I think to solve the EntryPointNotFound problem I will also have to modify some bundle project setting - but I don't know how... Please help me...

Lots and Lots of thanks!

Edit

  1. I saw this thread suggesting that since Xcode is using g++ to compile, I will need extern "C" even if my unmanaged code is in pure C. I changed my target setting in Xcode4 for "Compiler for C/C++/Objective-C" from Apple LLVM 3.0 to LLVM GCC 4.2, but I still get the same exception.
  2. I also saw this mono documentation that says mono is using GLib to load libraries, and Glib has a bug on Mac OS X which is that it doesn't recognize .dylib libraries. I deleted the .dylib libraries and tried again but I was till getting the same exception.
  3. Also Apple's documentation says that every loadable bundle must have a principal class, and if user doesn't specify which class is the principal class, NSBundle will use the first class shown in the Xcode project as the principal class. Well, I guess the bundle that I created is a loadable bundle, but because it's merely a static library built from C, it literally doesn't have any class. When I looked at my project's info.plist, the Principal Class entry is just empty. Could this be the problem? If so, how do I solve it?
  4. Also I saw something on Apple's documentation that I don't quite understand:

    If your loadable bundle is a plug-in, the host application developer usually provides an interface for the plug-in architecture in a framework. This framework typically contains a class that all plug-in principal classes inherit from, or a protocol (formal or informal) for the plug-in’s principal class to adopt.

    I am pretty sure the loadable bundle I create is a plugin. I am importing the bundle into Unity3D. Does that mean I should define a principal class from Unity? How?

Was it helpful?

Solution

The problem has a simple solution:

try out whatever function that is giving you the EntryPointNotFoundException in the test.c file first.

By "try out" I mean, have the function called in your main() and test it out in C first.

In my case, the function that throws out the EntryPointNotFoundException is called ccn_run(). So I did the following things:

  1. add a main() function to test.c
  2. type ccn_run() in the main() function
  3. add a command line target in Xcode project and test it out

I tried it out and the function is working alright in C, now the magical thing is that when I rebuild the bundle (without deleting the main() function and the ccn_run() call inside it), Unity can call the ccn_run() function without problem!

I couldn't explain why this solves my problem, but this has been working for me for almost a month now. Not long ago Xcode upgraded to 4.3.2 and I tried the same approach again, still works. I guess perhaps adding a main() function helps defining the entry point?

Finally, I documented the whole process of importing C code to Unity and I am glad to share here: https://docs.google.com/document/d/1vAeupNQlBTY3y3Bma5Jo_Hs4JRYm6FoEc4vQN0WBGNg/edit

My code sample:

  1. Xcode project: https://github.com/CherryQu921/CCNxPlugin
  2. Unity project: https://github.com/CherryQu921/cqs

Hope this answer especially my tutorial helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top