Interaction between Unity and iOS (3) - common interaction examples

【Preface】

The previous two articles introduced the principle of the interaction between Unity and iOS in detail. I believe that after reading it carefully, you will basically understand it. Of course, you may need to spend several hours to understand it. What is missing now is the specific calling code. I believe you can actually sort it out a little bit by yourself, but it will take a lot of time to dig around. Here we directly give examples of common interactive codes.

[Basic interaction]

Pass basic data types and sring types

public class Sample : MonoBehaviour 
{
    [DllImport("__Internal")]
    static extern void PassIntAndString (int a, string b);
}
extern "C" void PassIntAndString(int a,const char* b)
{
    NSLog(@"a = %d", a);
    NSString *str = [NSString stringWithUTF8String:b];
    NSLog(@"%@", str);
}

Pass an array of primitive data types

Sometimes there is a lot of data to be transferred, such as the data of a picture, an array may be used at this time

public class Sample : MonoBehaviour 
{
    [DllImport("__Internal")]
    private static extern void SendImageData (int length, int[] data);
}
extern "C" void SendImageData(int length,int* data)
{
        for (int i = 0; i < length; i++) {
            NSLog(@"imagedata %d : %d", i, data[i]);
        }
}

Let OC directly call back the C# function through MonoPInvoke

Generally speaking, we will use UnitySendMessage to implement OC to call C#, even for callback functions. Of course, UnitySendMessage will be slower when it comes to finding transforms. If there is a requirement for performance, you need to use PInvoke to implement the callback. It is thread-safe when using UnitySendMessage, and you must maintain thread safety when using PInvoke.

public class Sample:MonoBehaviour
{

//回调参数必须有MonoPInvokeCallBack,而且是static的
[MonoPInvokeCallback(typeof(CallBack))]
public static int PassCallBack(string url) {
    
}

[DllImport("__Internal")]
private static extern void SetCallBack(CallBack cb );

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int CallBack(string url);


private void Set ()
{
    SetCallBack (PassCallBack);//直接把函数指针传递过去
}
        
}

#if defined(__cplusplus)
extern "C"
{
#endif

    // C#设置过来的函数指针类型
    typedef int (*PassCallBack)(const char*); 
    static PassCallBack callBack;
    void SetCallBack(PassCallBack cb) {
        callBack = cb;
    }

#if defined(__cplusplus)
}
#endif


void SetUrl(const char* url) {//回调
    if (callBack != nil) {
        callBack(url);
    }
}

OC passes an array of basic data types to C#

public class Sample:MonoBehaviour
{

//回调参数必须有MonoPInvokeCallBack,而且是static的
[MonoPInvokeCallback(typeof(CallBack))]
public static int PassCallBack(int length,IntPtr data) {
        byte[] buffer = new byte[length];         
        Marshal.Copy(data, buffer, 0, length);//将数据拷贝出来
}

[DllImport("__Internal")]
private static extern void SetCallBack(CallBack cb);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int CallBack(int length,IntPtr data);


private void Set ()
{
    SetCallBack (PassCallBack);//直接把函数指针传递过去
}
        
}

#if defined(__cplusplus)
extern "C"
{
#endif

    // C#设置过来的函数指针类型
    typedef int (*PassCallBack)(int,void*); 
    static PassCallBack callBack;
    void SetCallBack(PassCallBack cb) {
        callBack = cb;
    }

#if defined(__cplusplus)
}
#endif


void SendData(int length) {//回调
    NSMutableArray *mutableArray = [NSMutableArray array];
    NSArray *array = [NSArray arrayWithArray:mutableArray];
    if (callBack != nil) {
        callBack(length,array);
    }
}

Pass a C# object

There are two ways to transfer objects, one is to serialize the object into an array, which is equivalent to passing an array of basic data types, which will not be described here, and then deserialize and restore the object; the other is to pass the object pointer out, similar to Pass function pointers.

object pointer passing

using System.Runtime.InteropServices;

public class Sample {
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void CallBack(IntPtr objectPtr);

    [DllImport("__Internal")]
    private static extern void PassObject(IntPtr objectPtr, CallBack callback);

    [MonoPInvokeCallback(typeof(CallBack))]
    private static void GetObject(IntPtr objectPtr) {
        GCHandle handle = (GCHandle) objectPtr;
        //从指针读取TestObjet
        TestObjet test = handle.Target as TestObjet;
        handle.Free ();
    }

    private static void Set() {
        TestObject test = new TestObject();
        IntPtr objectPtr = (IntPtr)GCHandle.Alloc (TestObject);
        PassObject (objectPtr, GetObject);
    }
}


public class TestObjet
{
    public int a;
    public bool b;
}

[complex interaction]

iOS and Unity interface jump

The two interface jumps are actually to replace the display screen, and the screen display on iOS is in UIWindow, just modify the rootViewController of UIWindow.

Integrate Unity as a library into Android or iOS

【reference】 

Interaction between Unity3D and iOS - Programmer Sought

Unity - Manual: Building plug-ins for iOS

iOS and Unity Messaging (Swift and C#) - Short Book (jianshu.com) 

Guess you like

Origin blog.csdn.net/enternalstar/article/details/131589512