Writing Native IOS and Android Unity Plugins

105 24
We just released our latest AppWarp Unity SDK update which includes support for building for iOS and Android from Unity Free. Since Unity restricts the use of.Net sockets on these platforms, native socket APIs (BSD C socket) have to be used if you want to do socket communication. In this post I will share my experience and on how we went about doing this.

There are two requirements when communicating with native unmanaged C code from managed.Net C# code. First you need to be able to call functions with arguments from C# to C and the second is to return data from native code back to C#. The below diagram illustrates how the code is structured.
We will use the example of a library for creating a native socket and returning its socket descriptor. Then we will see how we can read data from the native socket by passing the socket descriptor and a managed buffer which will be filled in by the native library code.

Building the plugins:

Lets first understand how we build the native plugins. For iOS, this is quite straight forward as you simply have to create a new ‚¬"iOS Framework and Library‚¬ project from XCode. Then add a C file to it and write your native code in it. For example in our case we create a file Socket.c and add the function in it (skipped the header include statements for brevity).
Compile and build from XCode and it will generate the library file (eg: libiOSNativeSocket.a in my case).

In case of Android, you'll need to use Android NDK to build the library. Download and add ndk-build to your path. While its useful to have a basic understanding of how NDK works but not absolutely required for the purpose of this post. Add your C file in a folder and name it ‚¬"jni‚¬. In this folder, you also need to add a file named Android.mk. It should look like below.

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS:= -llog
LOCAL_MODULE:= socket_android
LOCAL_SRC_FILES:= Socket.c
include $(BUILD_SHARED_LIBRARY)
Now navigate to the parent directory of the jni folder and execute ndk-build command. If successful, it will create a libs folder and put the generated library in it (eg: libsocket_android.so in my case).

Calling the plugin code from Unity

Now that we've built the plugins, we are ready to call them from Unity code. You first need to declare the native functions that you will use in managed code.
Note that the ‚¬"__Internal‚¬ name is used for iOS plugins. For android plugins you need to use the name of the native library that you have built for example if your android library's name is ‚¬"libsocket_android.so‚¬, you will declare a function
Note that name should not include the prefix (‚¬lib') nor the extension (‚¬.so') of the filename.

Once declared you can use the functions in your application. Note that its a good practice to check the platform when invoking these methods in Unity.
Passing data buffers between Unity and native code

Now we've covered the basic setup of communication across managed C# Unity and unmnagaed C library, we can look at a slightly more trick use case. The scenario is that we want to create buffer (byte array) in C# and pass it to the native library. The native library will fill it with what it reads from the socket and return the number of bytes read.
The corresponding managed C# code which uses this is non-trivial. The declaration of this in C# code is done as follows.
To using this native method in C# code, we first create a byte array. Then we need to get the native handle of this memory and tell the Mono GC to pin it. This is so that the GC doesn't free this memory while its being used by the native library. Once the function returns, we call free to inform the GC that the native handle is not being used anymore.

Click here to read the full Article...
Source...

Leave A Reply

Your email address will not be published.