自己编写库模块,Win&Android联调总结一

libGameNet模块Win&Android联调总结一

作者:JackJCracker) 邮箱:[email protected]

作者很赖还是不想上传图片 需要图片和配置实例的来这里下载:下载

在正式开始项目前,需要对各个基础模块做出Demo,本文档记录的是在写通用网络模块时候,WIN平台和Android平台联调碰到的问题。

 

1. WIN平台

WIN平台调试起来非常方便  一般不会出现什么问题。但是因为首先做的是win平台。所以不需要自己手写配置文件(也就是这个问题,导致在移植到android时出现一系列问题)

 

win平台中,我是依照如下步骤操作

A. 创建核心库libGameNet:直接创建cocos2d-x项目,删除不需要的其他目录,剩下结构如图所示

 

B. 创建应用层:直接创建cocos2d-x项目,保留所有创建文件。

 

其中libGameNet是后一步拷贝过来的

C. 拷贝libGameNetNetworkDemo(见上一步的截图)

D. 因为libGameNet要负责Protobuffer的序列化和反序列化,因此依赖于protobuffer。同时为了方便Network也使用protobuffer,将protobuffer2.5.0复制到networkDemo下的cocos2d/external/ 如下图:

 

E. 打开networkDemo,添加项目依赖 protobuffer和 libgamenet (添加办法请百度)

 

F. 因为libGameNet是直接创建cocos2d-x项目生成的。模式是exe格式。这里需要设置为lib模式。Protobuffer自带的vsproject已经指定其为lib 不需要自己配置

 

G. libGameNet添加libProtobuffer引用

 

H. networkDemo添加libGameNet引用

 

I. 其中具体涉及的代码略过,编译运行。

 

其中左边是服务端 右边是客户端。

 

服务端接受ok

 

设置断点观察服务端返回protobuffer的值。 确实返回了jcracker0 jcarcker1

J. 自此 win平台ok

Android平台联调

1. 在上面的操作中win平台基本可以平稳的跑起来。测试了在多线程和数据包过大情况下数据的传输。基本没问题。下载移植到android平台。总体流程是。编写libGameNetandroid.mk-->解决ant构建问题(可选,如果用vs2012+visual GDB方式打包的话)-->导入eclipse--->解决eclipse问题-->解决NDK编译问题-->生成apk--->利用vs2012+visual GDB联调(具体联调 可参见visual GDB 官方文档),

2.  另一个文档可参考http://my.oschina.net/wpracker/blog/295677

3. 具体来讲

a) Protobufferandroid.mk在以前写过 可以直接拿过来用,这里留一份备用:

 

在使用全新环境时,记得./configure 一次protobffer 生成必要文件

Protobuffer android.mk:

LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

#目标

TARGET_CPU_ABI := armeabi

#TARGET_CPU_ABI := armeabi-v7a

#TARGET_CPU_ABI := armeabi-v7a-hard

#TARGET_CPU_ABI := armeabi

 

#设置c++11头文件路径和链接路径

prebuilt_stdcxx_PATH := E:\android-ndk-r9d-windows-x86_64\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8

 

LOCAL_C_INCLUDES += \

$(prebuilt_stdcxx_PATH)/include \

    $(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI)/include

LOCAL_C_INCLUDES += E:\ylss\project\NewStartDemo\NetworkDemo\NetworkDemo\cocos2d\external\protobuf-2.5.0\src

 

$(warning $(prebuilt_stdcxx_PATH))

#LOCAL_LDFLAGS += -L$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI) -lgnustl_static -lsupc++

LOCAL_STATIC_LIBRARIES += -L$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI) -lgnustl_static -lsupc++

LOCAL_MODULE := protobuf_static

 

LOCAL_MODULE_FILENAME := libprotobuf

 

LOCAL_CPP_EXTENSION := .cc

 

LOCAL_SRC_FILES := \

src/google/protobuf/io/coded_stream.cc\

src/google/protobuf/stubs/common.cc \

src/google/protobuf/descriptor.cc \

src/google/protobuf/descriptor.pb.cc\

src/google/protobuf/descriptor_database.cc\

src/google/protobuf/dynamic_message.cc\

src/google/protobuf/extension_set.cc\

src/google/protobuf/extension_set_heavy.cc\

src/google/protobuf/generated_message_reflection.cc \

src/google/protobuf/generated_message_util.cc \

src/google/protobuf/io/gzip_stream.cc \

src/google/protobuf/compiler/importer.cc\

src/google/protobuf/message.cc\

src/google/protobuf/message_lite.cc \

src/google/protobuf/stubs/once.cc \

src/google/protobuf/compiler/parser.cc\

src/google/protobuf/io/printer.cc \

src/google/protobuf/reflection_ops.cc \

src/google/protobuf/repeated_field.cc \

src/google/protobuf/service.cc\

src/google/protobuf/stubs/structurally_valid.cc \

src/google/protobuf/stubs/strutil.cc\

src/google/protobuf/stubs/substitute.cc \

src/google/protobuf/stubs/stringprintf.cc \

src/google/protobuf/text_format.cc\

src/google/protobuf/io/tokenizer.cc \

src/google/protobuf/unknown_field_set.cc\

src/google/protobuf/wire_format.cc\

src/google/protobuf/wire_format_lite.cc \

src/google/protobuf/io/zero_copy_stream.cc\

src/google/protobuf/io/zero_copy_stream_impl.cc \

src/google/protobuf/io/zero_copy_stream_impl_lite.cc

 

#LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include/protobuf

 

#LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/protobuf

#LOCAL_CFLAGS := -std=c99

#LOCAL_CFLAGS += -std=c++11 -stdlib=libstdc++ -Wno-error=c++11-narrowing

 

include $(BUILD_STATIC_LIBRARY)

b) libGameNetandroid.mk变化较大不能再原来基础上修改。

 

#LOCAL_PATH := $(call my-dir)

LOCAL_PATH := E:\ylss\project\NewStartDemo\NetworkDemo\NetworkDemo

 

include $(CLEAR_VARS)

 

$(call import-add-path,$(LOCAL_PATH)/cocos2d)

$(call import-add-path,$(LOCAL_PATH)/cocos2d/external)

$(call import-add-path,$(LOCAL_PATH)/cocos2d/cocos)

 

#TARGET_CPU_ABI := armeabi

#TARGET_CPU_ABI := armeabi-v7a

#TARGET_CPU_ABI := armeabi-v7a-hard

#TARGET_CPU_ABI := armeabi

 

#设置c++11头文件路径和链接路径

#prebuilt_stdcxx_PATH := E:\android-ndk-r9d-windows-x86_64\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8

 

#LOCAL_C_INCLUDES += \

$(prebuilt_stdcxx_PATH)/include \

    $(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI)/include

 

#LOCAL_LDFLAGS += -L$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI) -lgnustl_static -lsupc++

    

LOCAL_MODULE := gamenet_static

 

LOCAL_MODULE_FILENAME := libgamenet

 

AL_CPP_EXTENSION := .cpp

 

LOCAL_SRC_FILES := $(LOCAL_PATH)/libGameNet/Classes/JackInetAdress.cpp \

                   $(LOCAL_PATH)/libGameNet/Classes/JackNetDelegate.cpp\

$(LOCAL_PATH)/libGameNet/Classes/JackSocket.cpp

 

LOCAL_C_INCLUDES := $(LOCAL_PATH)/libGameNet/Classes

 

LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static

LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static

LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static

 

# LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static

# LOCAL_WHOLE_STATIC_LIBRARIES += cocosbuilder_static

# LOCAL_WHOLE_STATIC_LIBRARIES += spine_static

# LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static

# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static

# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static

LOCAL_WHOLE_STATIC_LIBRARIES += protobuf_static

 

LOCAL_STATIC_LIBRARIES := lib_game_net

   

include $(BUILD_STATIC_LIBRARY)

 

$(call import-module,.)

$(call import-module,audio/android)

 

# $(call import-module,Box2D)

# $(call import-module,editor-support/cocosbuilder)

# $(call import-module,editor-support/spine)

# $(call import-module,editor-support/cocostudio)

# $(call import-module,network)

# $(call import-module,extensions)

$(call import-module,external/protobuf-2.5.0)

关键点用红色标记出来了,其中BUILD_STATIC_LIBARAY是之前联调失败的关键。当时因为android.mk是复制的networkDemoandroid.mk 而应用层 默认是打包成动态链接库(BUILD_SHARED_LIBRARY)的。这导致的问题是libgamenet在运行过程中需要动态加载cocos2d-x的库和 protobuffer的动态库之前在联调过程中发现,运行到了libgamenet总会莫名其妙的关闭。找了好久的原因。而且在libgamenet中使用了cocos2d-xlog函数,有一部打印出来 然后马上死掉了。现在想来就是cocos2d-x.so可能没加载。后来修改为BUILD_STATIC_LIBRARY后 就没出现这个问题了。

 

这是libgamenet中一句打印语句。之前是直接写成log(xxx) 然后就会死在这里。后来我怀疑是cocos2d-x包没加载。将其修改为printf发现就不会死掉。由此确认确实是BUILD_SHARED_LIBARARY的原因。 这里JACKLog是一个宏定义而已。

 

当时用这个宏来判断是不是log的问题。

c) 可选(使用vs2012+visual gdb构建项目)

这一步是可选项目。Visual gdb支持的。但是后面发现这一步是不需要的。但是可以作为过程了解。

注意事项。

VS2012 + visual GDB调试android

1. Android 使用android打包过程出现很多问题  但是都可以解决。 Crunch 删除就好了

2. Build.xml 698 打开E:\ylss\project\NewStartDemo\NetworkDemo\NetworkDemo\cocos2d\cocos\platform\android\java 下的打开proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

3. 提示 mutle什么的是 cocos2d-x的包重复了。 打开eclipse build_path中去掉重复的src 重新打包就好了

其中3中,在eclipse打包过程中, 添加linksrc是必须的 不然不能打包 而ant构建又不能有 所以看你自己选择的打包工具

 

eclipse中,这两个都指向同一个目录。Eclipse打包需要这样才能避免出现找不到cocos2d-x-activtiy is not type之类的错误。 而是用ant打包又不许移除掉一个

d) 这里列出其他配置文件的设置一遍复

 

开启gdb 方便联调的时候设置断点。完整的build_native.py:

#!/usr/bin/python

# build_native.py

# Build native codes

 

 

import sys

import os, os.path

import shutil

from optparse import OptionParser

 

def check_environment_variables_sdk():

    ''' Checking the environment ANDROID_SDK_ROOT, which will be used for building

    '''

 

    try:

        SDK_ROOT = os.environ['ANDROID_SDK_ROOT']

    except Exception:

        print "ANDROID_SDK_ROOT not defined. Please define ANDROID_SDK_ROOT in your environment"

        sys.exit(1)

 

    return SDK_ROOT

 

def check_environment_variables():

    ''' Checking the environment NDK_ROOT, which will be used for building

    '''

 

    try:

        NDK_ROOT = os.environ['NDK_ROOT']

    except Exception:

        print "NDK_ROOT not defined. Please define NDK_ROOT in your environment"

        sys.exit(1)

 

    return NDK_ROOT

 

def select_toolchain_version():

    '''Because ndk-r8e uses gcc4.6 as default. gcc4.6 doesn't support c++11. So we should select gcc4.7 when

    using ndk-r8e. But gcc4.7 is removed in ndk-r9, so we should determine whether gcc4.7 exist.

    Conclution:

    ndk-r8e  -> use gcc4.7

    ndk-r9   -> use gcc4.8

    '''

 

    ndk_root = check_environment_variables()

    if os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.8")):

        os.environ['NDK_TOOLCHAIN_VERSION'] = '4.8'

        print "The Selected NDK toolchain version was 4.8 !"

    elif os.path.isdir(os.path.join(ndk_root,"toolchains/arm-linux-androideabi-4.7")):

        os.environ['NDK_TOOLCHAIN_VERSION'] = '4.7'

        print "The Selected NDK toolchain version was 4.7 !"

    else:

        print "Couldn't find the gcc toolchain."

        exit(1)

 

def do_build(cocos_root, ndk_root, app_android_root,ndk_build_param,sdk_root,android_platform,build_mode):

 

    ndk_path = os.path.join(ndk_root, "ndk-build")

 

    # windows should use ";" to seperate module paths

    platform = sys.platform

    if platform == 'win32':

        ndk_module_path = 'NDK_MODULE_PATH=%s;%s/external;%s/cocos' % (cocos_root, cocos_root, cocos_root)

    else:

        ndk_module_path = 'NDK_MODULE_PATH=%s:%s/external:%s/cocos' % (cocos_root, cocos_root, cocos_root)

 

    if ndk_build_param == None:

        command = '%s -C %s %s' % (ndk_path, app_android_root, ndk_module_path)

    else:

        command = '%s -C %s %s %s' % (ndk_path, app_android_root, ''.join(str(e) for e in ndk_build_param), ndk_module_path)

    if os.system(command) != 0:

        raise Exception("Build dynamic library for project [ " + app_android_root + " ] fails!")

    elif android_platform is not None:

       sdk_tool_path = os.path.join(sdk_root, "tools/android")

       cocoslib_path = os.path.join(cocos_root, "cocos/2d/platform/android/java")

       command = '%s update lib-project -t %s -p %s' % (sdk_tool_path,android_platform,cocoslib_path) 

       if os.system(command) != 0:

          raise Exception("update cocos lib-project [ " + cocoslib_path + " ] fails!")     

       command = '%s update project -t %s -p %s -s' % (sdk_tool_path,android_platform,app_android_root)

       if os.system(command) != 0:

          raise Exception("update project [ " + app_android_root + " ] fails!")          

       buildfile_path = os.path.join(app_android_root, "build.xml")

       command = 'ant clean %s -f %s -Dsdk.dir=%s' % (build_mode,buildfile_path,sdk_root)

       os.system(command)

 

def copy_files(src, dst):

 

    for item in os.listdir(src):

        path = os.path.join(src, item)

        # Android can not package the file that ends with ".gz"

        if not item.startswith('.') and not item.endswith('.gz') and os.path.isfile(path):

            shutil.copy(path, dst)

        if os.path.isdir(path):

            new_dst = os.path.join(dst, item)

            os.mkdir(new_dst)

            copy_files(path, new_dst)

 

def copy_resources(app_android_root):

 

    # remove app_android_root/assets if it exists

    assets_dir = os.path.join(app_android_root, "assets")

    if os.path.isdir(assets_dir):

        shutil.rmtree(assets_dir)

 

    # copy resources

    os.mkdir(assets_dir)

    resources_dir = os.path.join(app_android_root, "../Resources")

    if os.path.isdir(resources_dir):

        copy_files(resources_dir, assets_dir)

 

def build(ndk_build_param,android_platform,build_mode):

 

    ndk_root = check_environment_variables()

    sdk_root = None

    select_toolchain_version()

 

    current_dir = os.path.dirname(os.path.realpath(__file__))

    cocos_root = os.path.join(current_dir, "../cocos2d")

 

    app_android_root = current_dir

    copy_resources(app_android_root)

    

    if android_platform is not None:

sdk_root = check_environment_variables_sdk()

if android_platform.isdigit():

android_platform = 'android-'+android_platform

else:

print 'please use vaild android platform'

exit(1)

    if build_mode is None:

       build_mode = 'debug'

    elif build_mode != 'release':

        build_mode = 'debug'

#jcracker add

    ndk_build_param = 'NDK_DEBUG=1'

    do_build(cocos_root, ndk_root, app_android_root,ndk_build_param,sdk_root,android_platform,build_mode)

 

# -------------- main --------------

if __name__ == '__main__':

 

    parser = OptionParser()

    parser.add_option("-n", "--ndk", dest="ndk_build_param", help='parameter for ndk-build')

    parser.add_option("-p", "--platform", dest="android_platform", 

    help='parameter for android-update.Without the parameter,the script just build dynamic library for project. Valid android-platform are:[10|11|12|13|14|15|16|17|18|19]')

    parser.add_option("-b", "--build", dest="build_mode", 

    help='the build mode for java project,debug[default] or release.Get more information,please refer to http://developer.android.com/tools/building/building-cmdline.html')

    (opts, args) = parser.parse_args()

    

build(opts.ndk_build_param,opts.android_platform,opts.build_mode)

 

 

Android.mk:

LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

$(call import-add-path,$(LOCAL_PATH)/../../cocos2d)

$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)

$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos)

 

LOCAL_MODULE := cocos2dcpp_shared

 

LOCAL_MODULE_FILENAME := libcocos2dcpp

 

AL_CPP_EXTENSION := .cc .cpp

 

#VisualGDBAndroid: AutoUpdateSourcesInNextLine

LOCAL_SRC_FILES := hellocpp/main.cpp

 

LOCAL_SRC_FILES += ../../Classes/AppDelegate.cpp \

                   ../../Classes/HelloWorldScene.cpp\

                   ../../Classes/TestName.cc

 

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes

#LOCAL_C_INCLUDES += ../../libGameNet/Classes

 

LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static

LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static

 

# LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static

# LOCAL_WHOLE_STATIC_LIBRARIES += cocosbuilder_static

# LOCAL_WHOLE_STATIC_LIBRARIES += spine_static

# LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static

# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static

# LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static

LOCAL_WHOLE_STATIC_LIBRARIES += gamenet_static

 

include $(BUILD_SHARED_LIBRARY)

 

$(call import-module,.)

$(call import-module,audio/android)

 

# $(call import-module,Box2D)

# $(call import-module,editor-support/cocosbuilder)

# $(call import-module,editor-support/spine)

# $(call import-module,editor-support/cocostudio)

# $(call import-module,network)

# $(call import-module,extensions)

$(call import-module,../libGameNet/proj.android/jni)

 

 

Application.mk:

APP_STL := gnustl_static

NDK_TOOLCHAIN_VERSION := 4.8 #4.8好像不能显示变量 下次尝试一下4.6

APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1 -std=c++11 -fsigned-char

APP_PLATFORM := android-16

APP_OPTIM := debug

APP_ABI := armeabi armeabi-v7a

LOCAL_C_FLAGS += -gdwarf-3 

 

下一篇:

libGameNet模块Win&Android联调总结二

你可能感兴趣的:(自己编写库模块,Win&Android联调总结一)