unity Object-c交互

一、unity 调用 Object-c

C/C++可以直接与Object-c交互,只要把文件后缀.m直接改成.mm,成为C/C++与Object-c混编文件.

C#又可以调用C/C++方法,所以C#就是可以与Object-c交互.

过程: C# 调用 C/C++ 调用 Object-c

1.C/C++调用Object-c

新建一个Test.mm文件,定义一个C风格接口函数。如:

Test.mm

extern "C"{
  void Log(char* arg){
    // 这里可以调用object-c的函数了
    // 如 [[ AlertView alloc] init]; ...
  }
}
//或
extern "C"{
  void Log(char* arg);
}
void Log(char* arg){
  // 这里可以调用object-c的函数了
  // 如 [[ AlertView alloc] init]; ...
}

将Test.mm文件放到unity工程的Assets/Plugins/iOS路径下

2.C#调用C/C++

新建TestPluginiOS.cs,如:

TestPluginiOS.cs

#if UNITY_IOS && !UNITY_EDITOR//只在iOS平台下编译
using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;//DllImport在此命名空间下

public class UniWebViewPlugin {
        [DllImport("__Internal")]
        private static extern void Log(string arg);
        //1.访问权限不一定是private
        //2.必须是static
        //参数是string而不是char*
}
#endif

注意:参数是string而不是char*,关于C与C#参数类型映射关系 http://blog.csdn.net/yatusiter/article/details/9221861


二、Object-c调用C#

Object-c中直接使用该方法调用C#函数

UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
//参数1:添加了要调用函数脚本组件的GameObject名
//参数2:回调函数的名字
//参数3:回调函数的参数

同Android开发中Java回调c#一样,三个参数都是字符串类型!但android开发中的第三个参数不能是null(若没有参数,可以用空字符串"",因为使用null程序会崩掉)

如果参数类型为NSString需要转换为UTF-8,如:

 NSString * url=@"www.qq.com";
 UnitySendMessage("GameObject1", "Log", [url UTF8String]);

官方介绍文档:https://docs.unity3d.com/Manual/PluginsForIOS.html


C#使用MonoPInvokeCallback,让C直接回调C#函数

.c文件

typedef struct Parameter {  
    int a;  
    int b;  
} Param;  
  
  
typedef void (*CallBack)(Param* p);  
  
void TestFunc(CallBack cb){  
    Param p;  
    p.a = 10;  
    p.b = 20;  
    cb(&p);  
}  

cs文件

public class NewBehaviourScript : MonoBehaviour {  
  
    [StructLayout(LayoutKind.Sequential)]  
    struct Parameter {  
       public int a;  
       public int b;  
    }  
  
    delegate void CallBack(IntPtr param);  
  
    [DllImport("TestLib")]  
    static extern void TestFunc(CallBack cb);  
  
    [MonoPInvokeCallback(typeof(CallBack))]  
    static void CallBackFunc(IntPtr param) {  
       var p = (Parameter)Marshal.PtrToStructure(param, typeof(Parameter));  
       Debug.Log("a:" + p.a + " b:" + p.b);  
    }  
  
    // Use this for initialization  
    void Start () {  
        TestFunc(CallBackFunc);  
    }  
      
    // Update is called once per frame  
    void Update () {  
      
    }  
}  

更详细代码看这里:http://www.cnblogs.com/kingBook/p/6723620.html

三、oc字符串与c字符串转换和拷贝

以下代码放置在extern "C"{}外

NSString* MakeNSString (const char* string) {
    if (string) {
        return [NSString stringWithUTF8String: string];
    } else {
        return [NSString stringWithUTF8String: ""];
    }
}

char* MakeCString(NSString *str) {
    const char* string = [str UTF8String];
    if (string == NULL) {
        return NULL;
    }

    char* res = (char*)malloc(strlen(string) + 1);
    strcpy(res, string);
    return res;
}