Unity3D研究院之Android NDK编译C/C++结合Unity实现本地数据共享(二十八)
雨松MOMO
【Unity3D研究院之游戏开发】
围观13237次
37条评论
编辑日期:2012-08-09
字体:大 中 小
id="cproIframe_u1121907_1" width="300" height="250" src="http://pos.baidu.com/acom?adn=4&at=134&aurl=&cad=1&ccd=32&cec=UTF-8&cfv=11&ch=0&col=zh-CN&conOP=0&cpa=1&dai=1&dis=0&layout_filter=rank%2Ctabcloud<r=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3D3FYeI0yMaaYISMuEAoAz3uRTHfjCqcyup6-Wl2w6-bxFrKelh1t4ugMFDLu2wT4Gnhe6pPCU9cEaJSLcASIb7_%26wd%3Dunity%2520%25E6%258E%25A5%25E5%25AE%2589%25E5%258D%2593sdk%2520.so%26issp%3D1%26f%3D3%26ie%3Dutf-8%26tn%3Dbaiduhome_pg%26sug%3Dunity%2520%25E6%258E%25A5%25E5%25AE%2589%25E5%258D%2593sdk%26oq%3Dunity%2520%26inputT%3D718%26rsp%3D0<u=http%3A%2F%2Fwww.xuanyusong.com%2Farchives%2F1129&lunum=6&n=92004029_cpr&pcs=1579x891&pis=10000x10000&ps=369x1091&psr=1920x1080&pss=1579x409&qn=3f40c72217a648a1&rad=&rsi0=300&rsi1=250&rsi5=4&rss0=%23FFFFFF&rss1=%23FFFFFF&rss2=%230000FF&rss3=%23444444&rss4=%23008000&rss5=&rss6=%23e10900&rss7=&scale=&skin=&td_id=1121907&ti=Unity3D%E7%A0%94%E7%A9%B6%E9%99%A2%E4%B9%8BAndroid%20NDK%E7%BC%96%E8%AF%91C%2FC%20%20%E7%BB%93%E5%90%88Unity%E5%AE%9E%E7%8E%B0%E6%9C%AC%E5%9C%B0%E6%95%B0%E6%8D%AE%E5%85%B1%E4%BA%AB%EF%BC%88%E4%BA%8C%E5%8D%81%E5%85%AB%EF%BC%89%20%7C%20%E9%9B%A8%E6%9D%BEMOMO%E7%A8%8B%E5%BA%8F&tn=text_default_300_250&tpr=1429080887396&ts=1&version=2.0&xuanting=0&dtm=BAIDU_DUP2_SETJSONADSLOT&dc=2&di=u1121907&tt=1429080885649.1747.2091.2091" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="margin: 0px; padding: 0px; font-family: inherit;">
开始本篇文章之前我先为大家简单的介绍一下Android NDK编程的原理, 我们知道Android开发使用JAVA语言来编程它的运行效率要比C/C++低很多,为了让JAVA语言可以调用 C/C++ 这时候NDK就出现了,使用DNK可以很方便的实现 JAVA 与 C/C++之间的互相调用。NDK的工作原理是使用谷歌提供的NDK工具将C/C++的代码编译成 .so文件,最后使用JAVA代码与.so文件之间相互调用。下面我先说一下在Unity中结合Android NDK实现本地数据的共享的原理,如下图所示 ,Unity工程加入NDK后工程大致可分为三个部分 Android(JAVA) 、 C/C++(.so)、Unity(C#)它们之间是可以相互调用的,在之前的文章中我向大家介绍了 Android与Unity之间相互调用的原理,Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)。这种方式只能相互传递String字符串,少量数据传递时可以使用这种方式。如果是大量数据这样就有点限制了,其实我们可以把C/C++的代码做为一个中转站,实现两边的数据引用与共享。
首先在官网中下载NDK最新的安装包,安装包分为三个版本这里我下载使用的是MAC OS版本,最新版本已经到了R8。
下载地址:http://developer.android.com/sdk/ndk/index.html
OK,我们在Eclipse中创建一个Android工程,在res与src平级文件夹目录下创建一个jni的文件夹。接着在文件夹中创建两个代码文件,分别是C与C++还有一个配置文件Android.mk。
c.c代码一共分为两个方法,先说说方法Java_com_xys_UnityTestActivity_TestAddInt 这个方法是漏给Java代码调用的,jint表示此方法的返回值为整形,数据类型还可以是jlong 、jfloat、jdouble、 jobject、jboolean、jbyte、jchar、jshort,搞程序的一看就应该明白了吧?我就不一一解释了。 方法名中java开头是标准用法,com_xys表示当前程序的包名,UnityTestActivity表示当前类,TestAddInt表示方法名,在Android中就是调用这个方法的,这个方法实现了一个简单的整形相加的操作。在说说第二个方法int addInt(),这个方法是留给Unity中C#语言调用的,它的结构与上面不一样不能在Java代码中调用,同样它也就是实现整形相加的操作。
先是C的文件 c.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <string.h>
#include <jni.h>
//Android中java代码调用此方法
jint
Java_com_xys_UnityTestActivity_TestAddInt
(
JNIEnv*
env
,
jobject
thiz
,
jint
a
,
jint
b
)
{
return
addInt
(
a
,
b
)
;
}
//Unity中C#代码调用此方法
int
addInt
(
int
a
,
int
b
)
{
return
a
+
b
;
}
|
在看看C++文件,它和C文件的调用原理差不多,不过值得注意的是C++中一定要把需要调用的方法写在extern “C”{ } 中,否则无法调用。
cplus.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#include <string.h>
#include <jni.h>
//声明一个类
class
MyClass
{
public
:
static
float
add
(
float
a
,
float
b
)
{
return
a
+
b
;
}
}
;
//外部调用的方法需要写在这里
extern
"C"
{
jfloat
Java_com_xys_UnityTestActivity_TestAddFloat
(
JNIEnv
*
env
,
jobject
thiz
,
jfloat
a
,
jfloat
b
)
{
return
MyClass
::
add
(
a
,
b
)
;
}
float
addFloat
(
float
a
,
float
b
)
{
return
MyClass
::
add
(
a
,
b
)
;
}
}
|
再看看第三个配置文件,文件中比较重要的两个变量 LOCAL_MODULE表示生成出的.so的名称 LOCAL_SRC_FILES 表示需要编译的文件,如果是多个C/C++文件中间需要使用 \ 隔开。
Android.mk
|
LOCAL_PATH
:
=
$
(
call
my
-
dir
)
include
$
(
CLEAR_VARS
)
LOCAL_MODULE
:
=
xuanyusong
LOCAL_SRC_FILES
:
=
\
c
.
c
\
cplus
.
cpp
include
$
(
BUILD_SHARED_LIBRARY
)
|
OK ,此时C/C++代码的准备工作就做完了,下面我们学习如何把c.c 与 cplus.cpp 一个C文件与一个C++文件一同打包进.so文件中。首先打开终端,cd到刚刚创建的jni目录下,然后执行一开始下载的DNK开发包中的ndk-build命令,你可以直接在android-ndk-r8中找到ndk-build然后拖拽到终端中即可,如果代码没有错误如图所示表示.so文件编译成功。
再看看当前Android工程的目录结构,libs -> armeabi -> libxuanyusong.so 就是刚刚编译生成的.so文件,xuanyusong.so前面的lib是系统默认添加的,大家不必惊慌。
下面我们编写Java代码,学习如何在java代码中调用C/C++,代码比较简单在OnCreat()方法中分别调用C与C++的方法,并且弹出一个Toast显示在界面中。
UnityTestActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package
com
.
xys
;
import
android
.
os
.
Bundle
;
import
android
.
widget
.
Toast
;
import
com
.
unity3d
.
player
.
UnityPlayerActivity
;
public
class
UnityTestActivity
extends
UnityPlayerActivity
{
@
Override
public
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
//在这里调用.so中的两个方法,并且显示在屏幕中
Toast
.
makeText
(
getApplicationContext
(
)
,
"整形 = "
+
TestAddInt
(
1
,
2
)
+
" 浮点型 = "
+
TestAddFloat
(
1.5f
,
1.1f
)
,
Toast
.
LENGTH_LONG
)
.
show
(
)
;
}
//声明c.c中的TestAddInt方法
public
native
int
TestAddInt
(
int
a
,
int
b
)
;
//声明cplus.cpp中的TestAddFloat方法
public
native
float
TestAddFloat
(
float
a
,
float
b
)
;
static
{
//加载.so文件
System
.
loadLibrary
(
"xuanyusong"
)
;
}
}
|
好的,我们终于把Android的工程建立完毕。接着我们需要把工程拷贝至Unity的Android插件中, 插件的制作还有谁不会?? 不会的朋友请看之前的文章,这里就不赘述。如下图所示,Android插件已经制作完毕放在Unity中。目录结构如下所示。
编写test.cs脚本,实现通过C#脚本直接访问libxuanyusong.so文件,直接把test.cs挂在摄像机上。使用[DllImport ("xuanyusong")]来引入.so 的方法, 这里注意的是 一定要把.so文件名的lib 与后缀.so去掉, 最后将数据通过GUI显示在屏幕中。
test.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
using
UnityEngine
;
using
System
.
Collections
;
using
System
.
Runtime
.
InteropServices
;
public
class
test
:
MonoBehaviour
{
int
i
=
0
;
float
f
=
0.0f
;
//引用C 、C++中的方法
[
DllImport
(
"xuanyusong"
)
]
private
static
extern
int
addInt
(
int
a
,
int
b
)
;
[
DllImport
(
"xuanyusong"
)
]
private
static
extern
float
addFloat
(
float
a
,
float
b
)
;
void
Start
(
)
{
//调用方法中相加函数
i
=
addInt
(
1
,
2
)
;
f
=
addFloat
(
1.0f
,
2.2f
)
;
}
void
OnGUI
(
)
{
//将相加后的信息显示在屏幕中
if
(
i
!=
0
)
GUILayout
.
Label
(
" use c ="
+
i
)
;
if
(
f
!=
0.0f
)
GUILayout
.
Label
(
" use cplus ="
+
f
)
;
}
}
|
所有的工作已经做完,我们打包编译上真机,首先是在Android中调用.so时 弹出结果的Toast 。
然后是在Unity中调用.so后通过GUI绘制在屏幕中的结果,蛤蛤。Unity给力吧。。
最后雨松MOMO希望和大家一起进步,哇咔咔,啦啦啦,~~~本文下载内容包括 Android工程 与 Unity工程,欢迎大家下载学习。,不早了MOMO祝大家学习愉快并且Good night !
下载地址: http://vdisk.weibo.com/s/ab_Ll