PC的事實上根本不用說,畢竟C#和C++交互的文章已經夠多了,當然我自覺得經過幾次折騰后。差點兒全部游戲須要到的操作我都掌握了(各種傳參方法,各種坑,不懂的能夠留言問。盡管基本上沒人看。哈哈)
廢話不多說,我們主要來講兩大平臺——iOS和android——與unity的native代碼交互
這里啰嗦一下就是去網上搜都是各種蛋疼的東西,比方假設要調用unity C#的函數怎么辦,差點兒清一色是給出UnitySendMessage的方法。在項目中用這個簡直是作死。那么多函數那么復雜的參數你這個破函數頂個屁用啊。
iOS還好說。Android更是坑,竟然要你去和java代碼交互,簡單來說就是C/C++ -》 Java -》C#。而實際上大部分時候你根本不須要這么蛋疼,直接C/C++ -》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);
}
extern “C” 這樣的細節就不多說了,由于我直接建立的是.c文件所以不須要這個標記,這里直接用典型的回調函數做樣例,由于有了回調。你就不必考慮怎樣使用C/C++調用C#或者反過來,由于這個樣例實際上已經包括了信息的交換
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 () {
}
}
以上是unity的腳本。輸出a,b。
注意到關鍵沒,對,就是[MonoPInvokeCallback(typeof(CallBack))]
這個標簽。沒有這個標簽就無法回調成功。
使用這種方法就能夠保證編碼效率和運行效率,你不須要進行各種中間層的封裝。不需把字符串轉來轉去,這全然歸功于Mono的跨平臺機制。Unity僅僅是進行了一些簡便操作
另外須要注意的是Android可能須要編譯各種相應的.so。其有用AndroidStudio一下子全部編譯出來然后丟到unity就好了
還有在PC平臺以下不須要這個標簽!
事實上假設不是為了保護代碼,對于unity開發差點兒都能夠在C#中完畢,C#功能已經足夠強大了,對于Android保護C#也在上篇文章提到過,盡管個人并不知道安全性假設,唯一的提示就是使用Coroutine之后,反編譯無法看到其過程。可是我并不知道是否僅僅是移到別的地方去了。我個人在把一下敏感信息放在Coroutine里面來防止反編譯(盡管可能然并卵)