【COCOS2DX-LUA 脚本开发之十四】解决自定义cpp类通过tolua++ binding LuaCocos2d后编译到Android运行黑屏(没有调用自定义cpp类)的问题!

前端之家收集整理的这篇文章主要介绍了【COCOS2DX-LUA 脚本开发之十四】解决自定义cpp类通过tolua++ binding LuaCocos2d后编译到Android运行黑屏(没有调用自定义cpp类)的问题!前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

唉,首先说点闲话 – -。Himi搞了不短的时间,这个问题一直没有解决,最后终于在张大(cocos2dx引擎开发者之一 张小明)的指导下解决了此问题。

本章基于上一篇 【COCOS2DX-LUA 脚本开发之十三】 与之前的项目整合【Cocos2d-X(2.x) 游戏开发系列之二】cocos2dx最新2.x版本跨平台整合NDK+Xcode,Xcode编写&编译代码,Android导入打包运行即可!

在进入正文之前,讲解下一些基础知识:(当前Himi的版本是cocos2xx 2.1.2 hotfix)

第一部分:

编译过项目到Android的童鞋们肯定知道创建好的Android项目下的jni下的Android.mk 这个文件,如下:

@H_403_26@ 1 @H_301_27@
2 @H_301_27@
3 @H_301_27@
4 @H_301_27@
5 @H_301_27@
6 @H_301_27@
7 @H_301_27@
8 @H_301_27@
9 @H_301_27@
10 @H_301_27@
11 @H_301_27@
12 @H_301_27@
13 @H_301_27@
14 @H_301_27@
15 @H_301_27@
16 @H_301_27@
17 @H_301_27@
18 @H_301_27@
19 @H_301_27@
20 @H_301_27@
21 @H_301_27@
22 @H_301_27@
23 @H_301_27@
24 @H_301_27@
25 @H_301_27@
26 @H_301_27@
27 @H_301_27@
@H_403_26@ LOCAL_PATH := $(call my-dir) @H_301_27@
@H_301_27@
include $(CLEAR_VARS) @H_301_27@
@H_301_27@
LOCAL_MODULE := game_shared @H_301_27@
@H_301_27@
LOCAL_MODULE_FILENAME := libgame @H_301_27@
@H_301_27@
LOCAL_SRC_FILES := hellocpp/main.cpp \ @H_301_27@
../../Classes/AppDelegate.cpp @H_301_27@
@H_301_27@
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes @H_301_27@
@H_301_27@
LOCAL_STATIC_LIBRARIES := curl_static_prebuilt @H_301_27@
@H_301_27@
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static @H_301_27@
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static @H_301_27@
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_lua_static @H_301_27@
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static @H_301_27@
@H_301_27@
include $(BUILD_SHARED_LIBRARY) @H_301_27@
@H_301_27@
$(call import-module,cocos2dx) @H_301_27@
$(call import-module,CocosDenshion/android) @H_301_27@
$(call import-module,scripting/lua/proj.android/jni) @H_301_27@
$(call import-module,cocos2dx/platform/third_party/android/prebuilt/libcurl) @H_301_27@
$(call import-module,extensions) @H_301_27@ @H_301_27@
@H_301_27@ @H_301_27@

这个文件中,主要我们关注如下几个配置:‘

1. LOCAL_SRC_FILES : 编译到Android的本地的类cpp或c,比如自定义了一个类HSprite.h HSprite.cpp

那么需要添加到这个LOCAL_SRC_FILES 中,如下:

@H_403_26@ 1 @H_301_27@
2 @H_301_27@
3 @H_301_27@
@H_403_26@ LOCAL_SRC_FILES := hellocpp/main.cpp \ @H_301_27@
../../Classes/AppDelegate.cpp \ @H_301_27@
../../Classes/HSprite.cpp @H_301_27@ @H_301_27@
@H_301_27@ @H_301_27@

2.LOCAL_C_INCLUDES :编译的本地类所在的路径,例如你有一个HSprite类放在Himi的文件夹中,那么你可以如下形式添加

@H_403_26@ 1 @H_301_27@
2 @H_301_27@
3 @H_301_27@
4 @H_301_27@
5 @H_301_27@
6 @H_301_27@
7 @H_301_27@
8 @H_301_27@
@H_403_26@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \ @H_301_27@
$(LOCAL_PATH)/../../Classes/Himi @H_301_27@
@H_301_27@
那么在你其他的类进行引用Himi文件夹下的HSprite时,无需写完整路径,如下: @H_301_27@
#include "Himi/HSprite.h" @H_301_27@
@H_301_27@
可以直接如下导入: @H_301_27@
#include "HSprite.h" @H_301_27@ @H_301_27@
@H_301_27@ @H_301_27@

3. LOCAL_STATIC_LIBRARIES : 添加所需要链接的静态库

本章需要关注的是如下的配置:

4. call import-module : 编译对应的模块!

$(call import-module,cocos2dx) :具体是从NDK_MODULE_PATH 路径下的cocos2dx文件夹下的Android.mk

那么NDK_MODULE_PATH 是指向哪里呢?哪里设置呢?下面详细讲解!

第二部分:

编译过项目到Android的童鞋们肯定也知道build_native.sh这个文件,NDK_MODULE_PATH的路径也在此文件中进行设置,如下图:

如下:

@H_403_26@ 1 @H_301_27@
2 @H_301_27@
3 @H_301_27@
4 @H_301_27@
5 @H_301_27@
6 @H_301_27@
7 @H_301_27@
8 @H_301_27@
9 @H_301_27@
10 @H_301_27@
11 @H_301_27@
12 @H_301_27@
13 @H_301_27@
14 @H_301_27@
15 @H_301_27@
16 @H_301_27@
17 @H_301_27@
18 @H_301_27@
19 @H_301_27@
20 @H_301_27@
21 @H_301_27@
22 @H_301_27@
23 @H_301_27@
24 @H_301_27@
25 @H_301_27@
26 @H_301_27@
27 @H_301_27@
28 @H_301_27@
29 @H_301_27@
30 @H_301_27@
31 @H_301_27@
32 @H_301_27@
33 @H_301_27@
34 @H_301_27@
35 @H_301_27@
36 @H_301_27@
37 @H_301_27@
38 @H_301_27@
39 @H_301_27@
40 @H_301_27@ @H_311_404@ 41 @H_301_27@
42 @H_301_27@
43 @H_301_27@
44 @H_301_27@
45 @H_301_27@
46 @H_301_27@
47 @H_301_27@
48 @H_301_27@
49 @H_301_27@
50 @H_301_27@
51 @H_301_27@
52 @H_301_27@
53 @H_301_27@
54 @H_301_27@
55 @H_301_27@
56 @H_301_27@
57 @H_301_27@
58 @H_301_27@
59 @H_301_27@
60 @H_301_27@
61 @H_301_27@
62 @H_301_27@
63 @H_301_27@
64 @H_301_27@
65 @H_301_27@
66 @H_301_27@
67 @H_301_27@
68 @H_301_27@
69 @H_301_27@
70 @H_301_27@
71 @H_301_27@
72 @H_301_27@
73 @H_301_27@
74 @H_301_27@
75 @H_301_27@
76 @H_301_27@
77 @H_301_27@
78 @H_301_27@
79 @H_301_27@
80 @H_301_27@
81 @H_301_27@
82 @H_301_27@
83 @H_301_27@
84 @H_301_27@
85 @H_301_27@
86 @H_301_27@
87 @H_301_27@
88 @H_301_27@
89 @H_301_27@ @H_593_502@ 90 @H_301_27@
@H_403_26@ APPNAME= "Tuc4Android" @H_301_27@
@H_301_27@
# options @H_301_27@
@H_301_27@
buildexternalsfromsource= @H_301_27@
@H_301_27@
usage(){ @H_301_27@
cat << EOF @H_301_27@
usage: $0 [options] @H_301_27@
@H_301_27@
Build C/C++ code for $APPNAME using Android NDK @H_301_27@
@H_301_27@
OPTIONS: @H_301_27@
-s Build externals from source @H_301_27@
-h this help @H_301_27@
EOF @H_301_27@
} @H_301_27@
@H_301_27@
while getopts "sh" OPTION; do @H_301_27@
case "$OPTION" in @H_301_27@
s) @H_301_27@
buildexternalsfromsource=1 @H_301_27@
;; @H_301_27@
h) @H_301_27@
usage @H_301_27@
exit 0 @H_301_27@
;; @H_301_27@
esac @H_301_27@
done @H_301_27@
@H_301_27@
# paths @H_301_27@
@H_301_27@
if [ -z "${NDK_ROOT+aaa}" ];then @H_301_27@
echo "please define NDK_ROOT" @H_301_27@
exit 1 @H_301_27@
fi @H_301_27@
@H_301_27@
DIR= "$( cd " $( dirname "${BASH_SOURCE[0]}" ) " && pwd )" @H_301_27@
# ... use paths relative to current directory @H_301_27@
COCOS2DX_ROOT= "/Users/slater/Documents/cocos2d-2.1rc0-x-2.1.2-hotfix" @H_301_27@ @H_311_404@ APP_ROOT= "/Users/slater/Desktop/TestUserCpp/TestUserCpp" @H_301_27@
APP_ANDROID_ROOT= "/Users/slater/Desktop/TestUserCpp/TestUserCpp/proj.android" @H_301_27@
@H_301_27@
echo "NDK_ROOT = $NDK_ROOT" @H_301_27@
echo "COCOS2DX_ROOT = $COCOS2DX_ROOT" @H_301_27@
echo "APP_ROOT = $APP_ROOT" @H_301_27@
echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT" @H_301_27@
@H_301_27@
# make sure assets is exist @H_301_27@
if [ -d "$APP_ANDROID_ROOT" /assets ]; then @H_301_27@
rm -rf "$APP_ANDROID_ROOT" /assets @H_301_27@
fi @H_301_27@
@H_301_27@
mkdir "$APP_ANDROID_ROOT" /assets @H_301_27@
@H_301_27@
# copy resources @H_301_27@
for file in "$APP_ROOT" /Resources/* @H_301_27@
do @H_301_27@
if [ -d "$file" ]; then @H_301_27@
cp -rf "$file" "$APP_ANDROID_ROOT" /assets @H_301_27@
fi @H_301_27@
@H_301_27@
if [ -f "$file" ]; then @H_301_27@
cp "$file" "$APP_ANDROID_ROOT" /assets @H_301_27@
fi @H_301_27@
done @H_301_27@
@H_301_27@
# copy icons (if they exist) @H_301_27@
file= "$APP_ANDROID_ROOT" /assets/Icon-72.png @H_301_27@
if [ -f "$file" ]; then @H_301_27@
cp "$file" "$APP_ANDROID_ROOT" /res/drawable-hdpi/icon.png @H_301_27@
fi @H_301_27@
file= "$APP_ANDROID_ROOT" /assets/Icon-48.png @H_301_27@
if [ -f "$file" ]; then @H_301_27@
cp "$file" "$APP_ANDROID_ROOT" /res/drawable-mdpi/icon.png @H_301_27@
fi @H_301_27@
file= "$APP_ANDROID_ROOT" /assets/Icon-32.png @H_301_27@
if [ -f "$file" ]; then @H_301_27@
cp "$file" "$APP_ANDROID_ROOT" /res/drawable-ldpi/icon.png @H_301_27@
fi @H_301_27@
@H_301_27@
if [[ "$buildexternalsfromsource" ]]; then @H_301_27@
echo "Building external dependencies from source" @H_301_27@
"$NDK_ROOT" /ndk-build -C "$APP_ANDROID_ROOT" $* \ @H_301_27@
"NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/source" @H_301_27@
else @H_301_27@
echo "Using prebuilt externals" @H_301_27@
"$NDK_ROOT" /ndk-build -C "$APP_ANDROID_ROOT" $* \ @H_301_27@
"NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt" @H_301_27@ @H_593_502@ fi @H_301_27@ @H_301_27@
@H_301_27@ @H_301_27@

在之前我们整合项目编译到Android时其中我们需要关注的是COCOS2DX_ROOT、 APP_ROOT、 APP_ANDROID_ROOT这三个路径的设置。

那么本次我们关注的是最下方 NDK_MODULE_PATH 是用于配置搜索编译模块的基础路径!此路径与第一部分的Android.mk中call import-module 相关!

${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt”

表示两个路径,一个是COCOS2DX_ROOT的路径,另外一个是COCOS2DX_ROOT路径下的/cocos2dx/platform/third_party/android/prebuilt

通过如上两个知识点的简单的介绍,大家可能会对编译过程更深一步的理解。

现在开始讲解本章重点: 解决自定义cpp类通过tolua++ binding LuaCocos2d后编译到Android运行黑屏(没有调用自定义cpp类)的问题!

如果大家没有自定义类binding到LuaCocos2d中那么编译Android绝对是正确运行的,但是难免会自定义一些类供lua脚本使用,一般我们可以通过tolua++进行binding到LuaCocos2d中(参考Himi的另外一篇文章【COCOS2DX-LUA 脚本开发之四】使用tolua++编译pkg,从而创建自定义类让Lua脚本使用

当正确binding到LuaCocos2d后,我们iphone模拟器运行后一切正常,那么当编译到Android后,总是出现黑屏,并屏幕显示有0个精灵 !

错误出在哪里呢?!首先我们最容易想到的是检查看 Android项目下jni下的Android.mk中的LOCAL_SRC_FILES 是否包含了你自定义的类!确定是否参与编译了!

如果确定参与编译了,并Android项目能正常运行,但是还是运行黑屏的话,那么你可以打印lua中调用自定义类!最后会发现打印语句编译到Android后,根本没打印!基本上那就可以判定是LuaCocos2d这个类中并没有binding你自定义类!

有些童鞋就奇怪说可以确定xcode项目下的LuaCocos2d类中确实binding了自定义类啊!!

是的,但是你看到的只是ios项目所用的LuaCocos2d,真正编译到Android后的LuaCocos2d根本不是ios项目下的LuaCocos2d这个类!!

那么到底是哪里的LuaCocos2d被编译到Android了呢?其实不难发现,通过Android.mk中看到编译lua模块的语句:

$(call import-module,scripting/lua/proj.android/jni) : 我们可以知道它指向cocos2dx引擎下的scripting/lua/proj.android/jni/Android.mk

路径如下:

打开后内容如下:

@H_403_26@ 1 @H_301_27@
2 @H_301_27@
3 @H_301_27@
4 @H_301_27@
5 @H_301_27@
6 @H_301_27@
7 @H_301_27@
8 @H_301_27@
9 @H_301_27@
10 @H_301_27@
11 @H_301_27@
12 @H_301_27@
13 @H_301_27@
14 @H_301_27@
15 @H_301_27@
16 @H_301_27@
17 @H_301_27@
18 @H_301_27@
19 @H_301_27@
20 @H_301_27@
21 @H_301_27@
22 @H_301_27@
23 @H_301_27@
24 @H_301_27@
25 @H_301_27@
26 @H_301_27@
27 @H_301_27@
28 @H_301_27@
29 @H_301_27@
30 @H_301_27@
31 @H_301_27@
32 @H_301_27@
33 @H_301_27@
34 @H_301_27@
35 @H_301_27@
36 @H_301_27@
37 @H_301_27@
38 @H_301_27@
39 @H_301_27@
40 @H_301_27@ @H_311_404@ 41 @H_301_27@
42 @H_301_27@
43 @H_301_27@
44 @H_301_27@
45 @H_301_27@
46 @H_301_27@
47 @H_301_27@
48 @H_301_27@
49 @H_301_27@
50 @H_301_27@
51 @H_301_27@
52 @H_301_27@
53 @H_301_27@
54 @H_301_27@
55 @H_301_27@
56 @H_301_27@
57 @H_301_27@
58 @H_301_27@
59 @H_301_27@
60 @H_301_27@
61 @H_301_27@
62 @H_301_27@
63 @H_301_27@
64 @H_301_27@
65 @H_301_27@
66 @H_301_27@
67 @H_301_27@
68 @H_301_27@
69 @H_301_27@
@H_403_26@ LOCAL_PATH := $(call my-dir) @H_301_27@
include $(CLEAR_VARS) @H_301_27@
@H_301_27@
LOCAL_MODULE := cocos_lua_static @H_301_27@
@H_301_27@
LOCAL_MODULE_FILENAME := liblua @H_301_27@
@H_301_27@
LOCAL_SRC_FILES :=../../lua/lapi.c \ @H_301_27@
../../lua/lauxlib.c \ @H_301_27@
../../lua/lbaselib.c \ @H_301_27@
../../lua/lcode.c \ @H_301_27@
../../lua/ldblib.c \ @H_301_27@
../../lua/ldebug.c \ @H_301_27@
../../lua/ldo.c \ @H_301_27@
../../lua/ldump.c \ @H_301_27@
../../lua/lfunc.c \ @H_301_27@
../../lua/lgc.c \ @H_301_27@
../../lua/linit.c \ @H_301_27@
../../lua/liolib.c \ @H_301_27@
../../lua/llex.c \ @H_301_27@
../../lua/lmathlib.c \ @H_301_27@
../../lua/lmem.c \ @H_301_27@
../../lua/loadlib.c \ @H_301_27@
../../lua/lobject.c \ @H_301_27@
../../lua/lopcodes.c \ @H_301_27@
../../lua/loslib.c \ @H_301_27@
../../lua/lparser.c \ @H_301_27@
../../lua/lstate.c \ @H_301_27@
../../lua/lstring.c \ @H_301_27@
../../lua/lstrlib.c \ @H_301_27@
../../lua/ltable.c \ @H_301_27@
../../lua/ltablib.c \ @H_301_27@
../../lua/ltm.c \ @H_301_27@
../../lua/lua.c \ @H_301_27@
../../lua/lundump.c \ @H_301_27@
../../lua/lvm.c \ @H_301_27@
../../lua/lzio.c \ @H_301_27@
../../lua/print.c \ @H_301_27@
../../tolua/tolua_event.c \ @H_301_27@
../../tolua/tolua_is.c \ @H_301_27@ @H_311_404@ ../../tolua/tolua_map.c \ @H_301_27@
../../tolua/tolua_push.c \ @H_301_27@
../../tolua/tolua_to.c \ @H_301_27@
../../cocos2dx_support/CCLuaBridge.cpp \ @H_301_27@
../../cocos2dx_support/CCLuaEngine.cpp \ @H_301_27@
../../cocos2dx_support/CCLuaStack.cpp \ @H_301_27@
../../cocos2dx_support/CCLuaValue.cpp \ @H_301_27@
../../cocos2dx_support/Cocos2dxLuaLoader.cpp \ @H_301_27@
../../cocos2dx_support/LuaCocos2d.cpp \ @H_301_27@
../../cocos2dx_support/tolua_fix.c @H_301_27@
@H_301_27@
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../lua \ @H_301_27@
$(LOCAL_PATH)/../../tolua \ @H_301_27@
$(LOCAL_PATH)/../../cocos2dx_support @H_301_27@
@H_301_27@
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ \ @H_301_27@
$(LOCAL_PATH)/../../lua \ @H_301_27@
$(LOCAL_PATH)/../../tolua \ @H_301_27@
$(LOCAL_PATH)/../../../../cocos2dx \ @H_301_27@
$(LOCAL_PATH)/../../../../cocos2dx/include \ @H_301_27@
$(LOCAL_PATH)/../../../../cocos2dx/platform \ @H_301_27@
$(LOCAL_PATH)/../../../../cocos2dx/platform/android \ @H_301_27@
$(LOCAL_PATH)/../../../../cocos2dx/kazmath/include \ @H_301_27@
$(LOCAL_PATH)/../../../../CocosDenshion/include @H_301_27@
@H_301_27@
LOCAL_CFLAGS += -Wno-psabi @H_301_27@
LOCAL_EXPORT_CFLAGS += -Wno-psabi @H_301_27@
@H_301_27@
include $(BUILD_STATIC_LIBRARY) @H_301_27@ @H_301_27@
@H_301_27@ @H_301_27@

从这个mk文件内容中我们可以看到参与编译的LuaCocos2d类是相对于当前Android.mk 路径的 ../../cocos2dx_support/LuaCocos2d.cpp \

从上面的附上的图可以清楚的看到这个路径,是当前Android.mk的路径的上两层后的目录下的cocos2dx_support的LuaCocos2d.cpp文件

可能讲到这里,很多童鞋应该恍然大悟了吧!

虽然我们自定义类通过tolua++ binding到项目下的LuaCococs2d 中,但是参与Android编译的LuaCocos2d并不是你项目下的!

OK,那下面给出几种解决方式:

第一种:将我们项目下的已经binding好的LuaCococs2d类替换参与编译的LuaCococs2d类!

(注:LuaCococs2d.h中导入的自定义类路径,引用你项目下的对应类即可)

第二种: 将编译的Lua模块的Android.mk中的参与编译的LuaCococs2d路径改成自己项目下的LuaCococs2d路径即可。

第三种: 通过修改NDK_MODULE_PATH 路径,将其指向我们项目下的libs路径,然后将参与编译的缺少模块copy到我们的项目下对应路径即可!

这个问题其实比较容易解决,但是主要的是理解原理!否则会越忙越乱!

原文链接:https://www.f2er.com/cocos2dx/345463.html

猜你在找的Cocos2d-x相关文章