Unity native call reference
TL;DR: A lookup reference for the most common native calls on Android and iOS.
I sometimes implement native plugins for Unity and I constantly catch me asking the same questions. How do I transfer a string to Objective-C++ code again? How do I pass a array into Java code via the JNI bridge? I hope I can document the most cases so I have a look up reference. Naturally I want to share this, so everyone can profit from this. So here is a hopefully helpful reference for iOS and Android. I will ad more entries as soon as I encounter them in other projects. Feel free to comment in the comments section which native calls have you constantly searching the forums for answers?
Android
Bool
using UnityEngine;
namespace Android
{
public static class BoolMethod
{
public static void Call()
{
#if UNITY_EDITOR || UNITY_ANDROID
var nativeMethodsObj = new AndroidJavaObject("com.robinryf.nativecallmatrix.BoolMethod");
nativeMethodsObj.CallStatic("call", true);
#endif
}
}
}
package com.robinryf.nativecallmatrix;
public class BoolMethod {
/*
Make sure you use 'boolean' and not 'Boolean'. It is something completely different to the
JNI bridge.
*/
public static void call(boolean myBoolean)
{
Log.i("Received bool: " + myBoolean);
}
}
DataClass
using UnityEngine;
namespace Android
{
public static class DataClassMethod
{
private class DataClass
{
public int dataInt;
public bool dataBool;
#if UNITY_EDITOR || UNITY_ANDROID
public AndroidJavaObject ToJavaObject()
{
var obj = new AndroidJavaObject("com.robinryf.nativecallmatrix.DataClass");
obj.Set("dataInt", dataInt);
obj.Set("dataBool", dataBool);
return obj;
}
#endif
}
public static void Call()
{
#if UNITY_EDITOR || UNITY_ANDROID
var data = new DataClass();
data.dataInt = 10;
data.dataBool = true;
var nativeMethodsObj = new AndroidJavaObject("com.robinryf.nativecallmatrix.DataClassMethod");
nativeMethodsObj.CallStatic("call", data.ToJavaObject());
#endif
}
}
}
package com.robinryf.nativecallmatrix;
public class DataClassMethod {
public static void call(DataClass dataClass)
{
Log.i("Received dataClass: " + dataClass);
}
}
Float
using UnityEngine;
namespace Android
{
public static class FloatMethod
{
public static void Call()
{
#if UNITY_EDITOR || UNITY_ANDROID
var nativeMethodsObj = new AndroidJavaObject("com.robinryf.nativecallmatrix.FloatMethod");
nativeMethodsObj.CallStatic("call", 2.0f);
#endif
}
}
}
package com.robinryf.nativecallmatrix;
public class FloatMethod {
/*
Make sure you use 'float' and not 'Float'. It is something completely different to the
JNI bridge.
*/
public static void call(float myFloat)
{
Log.i("Received float: " + myFloat);
}
}
IntArray
using UnityEngine;
namespace Android
{
public static class IntArrayMethod
{
public static void Call()
{
#if UNITY_EDITOR || UNITY_ANDROID
var nativeMethodsObj = new AndroidJavaObject("com.robinryf.nativecallmatrix.IntArrayMethod");
nativeMethodsObj.CallStatic("call", new [] { 1, 2, 3 });
#endif
}
}
}
package com.robinryf.nativecallmatrix;
public class IntArrayMethod {
public static void call(int[] intArray)
{
Log.i("Received int array with length: " + intArray.length + " ints:");
for (int i = 0; i < intArray.length; i++) {
int element = intArray[i];
Log.i(element + "\n");
}
}
}
Int
using UnityEngine;
namespace Android
{
public static class IntMethod
{
public static void Call()
{
#if UNITY_EDITOR || UNITY_ANDROID
var nativeMethodsObj = new AndroidJavaObject("com.robinryf.nativecallmatrix.IntMethod");
nativeMethodsObj.CallStatic("call", 42);
#endif
}
}
}
package com.robinryf.nativecallmatrix;
public class IntMethod {
/*
Make sure you use 'int' and not 'Integer'. It is something completely different to the
JNI bridge.
*/
public static void call(int myInteger)
{
Log.i("Received int: " + myInteger);
}
}
String
using UnityEngine;
namespace Android
{
public static class StringMethod
{
public static void Call()
{
#if UNITY_EDITOR || UNITY_ANDROID
var nativeMethodsObj = new AndroidJavaObject("com.robinryf.nativecallmatrix.StringMethod");
nativeMethodsObj.CallStatic("call", "passedString");
#endif
}
}
}
package com.robinryf.nativecallmatrix;
/**
* Created by Robin on 28.11.2017.
*/
public class StringMethod {
public static void call(String myString)
{
Log.i("Received string: " + myString);
}
}
iOS
Bool
using System.Runtime.InteropServices;
namespace Ios
{
public static class BoolMethod
{
#if UNITY_EDITOR || UNITY_IOS
[DllImport ("__Internal")]
private static extern void _BoolMethod(bool myBool);
#endif
public static void Call()
{
#if UNITY_EDITOR || UNITY_IOS
_BoolMethod(true);
#endif
}
}
}
#import <Foundation/Foundation.h>
extern "C" void _BoolMethod(BOOL myBool)
{
NSLog(@"Got Bool: %d", myBool);
}
DataStruct
using System.Runtime.InteropServices;
namespace Ios
{
public static class DataStructMethod
{
[StructLayout(LayoutKind.Sequential)]
private struct DataStruct
{
public int myDataInt;
public float myDataFloat;
public float[] myDataFloatArray;
public float myDataFloatArrayLength;
}
#if UNITY_EDITOR || UNITY_IOS
[DllImport ("__Internal")]
private static extern void _DataStructMethod(DataStruct myDataStruct);
#endif
public static void Call()
{
#if UNITY_EDITOR || UNITY_IOS
var array = new[] {2.4f, 2.5f, 2.6f, 2.9f, 10.1f, 20.1f};
var myDataStruct = new DataStruct
{
myDataInt = 32,
myDataFloat = 19.3f,
myDataFloatArray = array,
myDataFloatArrayLength = array.Length
};
_DataStructMethod(myDataStruct);
#endif
}
}
}
#import <Foundation/Foundation.h>
struct DataStruct
{
int myDataInt;
float myDataFloat;
float* myDataFloatArray;
float myDataFloatArrayLength;
};
extern "C" void _DataStructMethod(DataStruct myDataStruct)
{
NSNumber* myInt = [NSNumber numberWithInt:myDataStruct.myDataInt];
NSLog(@"Got data struct with int: %@, float %f", myInt, myDataStruct.myDataFloat);
for (int i = 0; i < myDataStruct.myDataFloatArrayLength; i++) {
NSNumber* arrayNumber = [NSNumber numberWithFloat:myDataStruct.myDataFloatArray[i]];
NSLog(@"Got array number: %@", arrayNumber);
}
}
Float
using System.Runtime.InteropServices;
namespace Ios
{
public static class FloatMethod
{
#if UNITY_EDITOR || UNITY_IOS
[DllImport ("__Internal")]
private static extern void _FloatMethod(float myFloat);
#endif
public static void Call()
{
#if UNITY_EDITOR || UNITY_IOS
_FloatMethod(2.3f);
#endif
}
}
}
#import <Foundation/Foundation.h>
extern "C" void _FloatMethod(float myFloat)
{
NSNumber *myNumber = [NSNumber numberWithFloat: myFloat];
NSLog(@"Got float number: %@", myNumber);
}
IntArray
using System.Runtime.InteropServices;
namespace Ios
{
public static class IntArrayMethod
{
#if UNITY_EDITOR || UNITY_IOS
[DllImport ("__Internal")]
private static extern void _IntArrayMethod( int[] myIntArray, int size);
#endif
public static void Call()
{
#if UNITY_EDITOR || UNITY_IOS
var array = new[] {2, 4, 9, 10, 11};
_IntArrayMethod(array, array.Length);
#endif
}
}
}
#import <Foundation/Foundation.h>
extern "C" void _IntArrayMethod(int* array, int length)
{
NSMutableArray* myArray = [NSMutableArray array];
for (int i = 0; i < length; i++) {
int arrayMember = array[i];
[myArray addObject:[NSNumber numberWithInt:arrayMember]];
}
NSLog(@"Got int array with legth: %d and entries:", length);
for (int i = 0; i < [myArray count]; i++) {
NSNumber* number = [myArray objectAtIndex:i];
NSLog(@"%@", number);
}
}
Int
using System.Runtime.InteropServices;
namespace Ios
{
public static class IntMethod
{
#if UNITY_EDITOR || UNITY_IOS
[DllImport ("__Internal")]
private static extern void _IntMethod(int myInt);
#endif
public static void Call()
{
#if UNITY_EDITOR || UNITY_IOS
_IntMethod(42);
#endif
}
}
}
#import <Foundation/Foundation.h>
extern "C" void _IntMethod(int myInt)
{
NSNumber* myNumber = [NSNumber numberWithInt:myInt];
NSLog(@"Got int number: %@", myNumber);
}
String
using System.Runtime.InteropServices;
namespace Ios
{
public static class StringMethod
{
#if UNITY_EDITOR || UNITY_IOS
[DllImport ("__Internal")]
private static extern void _StringMethod(string myString);
#endif
public static void Call()
{
#if UNITY_EDITOR || UNITY_IOS
_StringMethod("Hello this is managed code.");
#endif
}
}
}
#import <Foundation/Foundation.h>
extern "C" void _StringMethod(const char* myString)
{
NSString* myNsString = [NSString stringWithUTF8String:myString];
NSLog(@"Got passed string: %@", myNsString);
}