前言
用游戲引擎開發(fā)的項目都是跨平臺的,在此拥峦,Android平臺暫且不提贴膘,因為java代碼的不熟悉以及未大量嘗試,所以不涉及到Android平臺略号,這里著重強調(diào)Unity,Cocos兩個引擎與oc,或c++做混編刑峡。
Unity開發(fā)語言 C#
Cocos開發(fā)語言 c++
Cocos引擎
說道混編,我們還是先來說說原生開發(fā)玄柠。IOS的原生開發(fā)是OC突梦,目標平臺是xcode。
oc語言是c的超集羽利,也就是說他既繼承了C宫患,也在之上做了大量的拓展。
這就奠定了OC能與C这弧,C++做混編的基礎(chǔ)娃闲。
我們既然談到Xcode編譯器虚汛,那么我想這個知識點大家必須要知道。
- 補充:混編就是我寫我的代碼皇帮,你寫你的代碼卷哩,做個橋梁調(diào)用彼此
- 源文件必須以.mm文件作為xcode object c++的擴展
- 這里我解釋下,.m .cpp文件在不混編的情況下存在是肯定的属拾,但是要把這兩者都兼容将谊,譬如兩者調(diào)用,就需要.mm文件了渐白,所有語言的橋接代碼源文件都是.mm 其實就是相當(dāng)于.cpp
cocos比unity開發(fā)簡單瓢娜,一個好處在于他可以直接在xcode里面編譯C++代碼。這意味著你可以隨時修改代碼重新編譯礼预。unity的等會再談眠砾。
我們剛才說過oc是c的超集,c++更不用說托酸,所以他們唯一的交互點就是c褒颈。結(jié)合上一節(jié)說的IOS上架之socket IPV6兼容問題里面有個oc源碼,我們就拿這個練手
C++肯定是想調(diào)用C++的代碼励堡,所以橋接我用C++方法去調(diào)用oc方法谷丸。
//ObjectHelper類下的getHostIp C++方法
const char* ObjectHelper::getHostIp(std::string hostip)
{
//將string 轉(zhuǎn)成 NsString
NSString *stroc = [NSString stringWithCString:hostip.c_str()
encoding:[NSString defaultCStringEncoding]];
//我把oc的這個方法寫了一個sign類,當(dāng)類方法
NSString* str =[sign getIPWithHostName:stroc];
return [str UTF8String];
}
這里其實唯一要注意的是數(shù)據(jù)的處理应结,所以用通用的const char*作為string 去傳遞數(shù)據(jù)刨疼。 其他的大體一樣。
getIPWithHostName:stroc 這個方法在上一篇文章里面有鹅龄,我就不多講了揩慕。
這個ObjectHelper類 當(dāng)然是.h .mm源文件格式。
- 再次申明 扮休,其實.mm完全可以理解成.cpp這種形式
Unity引擎
- Unity 一般用C#開發(fā)迎卤,所以這里做C++ 和OC的橋接
- C#和C的關(guān)系我也不說了,看字面上就能猜(好吧玷坠,其實我是不知道)但是不影響我們?nèi)グ凑誄方式寫代碼
C#和C++
- 先說動態(tài)庫調(diào)用蜗搔,也就是在C#中調(diào)用C++的DLL,DLL分兩種方式托管模式和非托管模式八堡。
- 托管模式:這種模式更多人推薦樟凄,因為C#能直接調(diào)用其對象,然后去訪問C++函數(shù)兄渺。其實不然缝龄,在復(fù)雜的庫(譬如我之前在git上找到的跨平臺的midi庫)面前,編譯都沒法成功。這里解釋下二拐,如果你能編譯成功那么你當(dāng)然是可以使用服鹅。
- 非托管模式:暴露extern "C" 的函數(shù)接口用來調(diào)用。這種模式使用起來很繁瑣百新,但是思維很簡單
這兩種模式的實現(xiàn)其實都有很多教程企软,在這里我就不一一贅述了。
關(guān)鍵詞:unity調(diào)用C++DLL
C#和OC
如果是IOS平臺下饭望,其實完全沒必要用DLL仗哨。
之前的MIDI方案就是如此。
- 用到的機制是Unity自帶的Plugins铅辞。
Plugins下的IOS文件能放.m .mm等文件厌漂,當(dāng)項目發(fā)布到Xcode上,作為文件去編譯斟珊。那么調(diào)用C++也好OC苇倡,也好都能用cocos那種方式去調(diào)用也就是在xcode里面用.mm橋接,用非托管模式去暴露接口然后調(diào)用囤踩。
extern "C"
{
void MIDIinit()
{
if(!rtmidi)
rtmidi =new RtMidiIn();
}
void Connet(int num)
{
rtmidi->openPort(num);
rtmidi->setCallback(&mycallback);
}
int getConnetNub()
{
return rtmidi->getPortCount();
}
}
當(dāng)然如果不是在OC平臺還是要以調(diào)用DLL去訪問C++代碼旨椒。
模式無非是托管和 非托管。
忘了說C#里面如何調(diào)用了
[DllImport("__Internal")]
private static extern int getConnetNub();
.mm文件和.m文件放在Plugins/IOS 下堵漱,這是個特殊文件夾综慎,無法再編輯器里面直接運行 ,需要發(fā)布Xcode之后勤庐,真機測試示惊。