GVKun编程网logo

cocos2dx 安卓makefile Android.mk,动态引用cpp地址(cocos动态加载)

23

想了解cocos2dx安卓makefileAndroid.mk,动态引用cpp地址的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于cocos动态加载的相关问题,此外,我们还将为您介绍关于关于

想了解cocos2dx 安卓makefile Android.mk,动态引用cpp地址的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于cocos动态加载的相关问题,此外,我们还将为您介绍关于 关于cocos2dx接Android sdk的一些坑、Android Cocos2dx-js 游戏 APP 逆向、Android cocos2dx游戏开发——示例程序HelloCpp源码分析、android-ndk – 从java(android)调用C(cocos2dx)方法进行我的应用内结算的新知识。

本文目录一览:

cocos2dx 安卓makefile Android.mk,动态引用cpp地址(cocos动态加载)

cocos2dx 安卓makefile Android.mk,动态引用cpp地址(cocos动态加载)

原因:

每次加一个cpp,都要改写Android.mk 一次,修改了引用脚本,就不用每次都该了。

修改LOCAL_SRC_FILES 的赋值


转自

http://suool.net/


原来的。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)





LOCAL_MODULE := cocos2dcpp_shared

LOCAL_MODULE_FILENAME := libcocos2dcpp

LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/HelloWorldScene.cpp

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

# _COCOS_HEADER_ANDROID_BEGIN
# _COCOS_HEADER_ANDROID_END


LOCAL_STATIC_LIBRARIES := cocos2dx_static

# _COCOS_LIB_ANDROID_BEGIN
# _COCOS_LIB_ANDROID_END

include $(BUILD_SHARED_LIBRARY)

$(call import-module,./prebuilt-mk)

# _COCOS_LIB_IMPORT_ANDROID_BEGIN
# _COCOS_LIB_IMPORT_ANDROID_END



修改后的:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)





LOCAL_MODULE := cocos2dcpp_shared

LOCAL_MODULE_FILENAME := libcocos2dcpp

# 遍历目录及子目录的函数
define walk
$(wildcard $(1)) $(foreach e,$(wildcard $(1)/*),$(call walk,$(e)))
endef
# 遍历Classes目录
ALLFILES = $(call walk,$(LOCAL_PATH)/../../Classes)
FILE_LIST := hellocpp/main.cpp
# 从所有文件中提取出所有.cpp文件
FILE_LIST += $(filter %.cpp,$(ALLFILES))
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)


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

# _COCOS_HEADER_ANDROID_BEGIN
# _COCOS_HEADER_ANDROID_END


LOCAL_STATIC_LIBRARIES := cocos2dx_static

# _COCOS_LIB_ANDROID_BEGIN
# _COCOS_LIB_ANDROID_END

include $(BUILD_SHARED_LIBRARY)

$(call import-module,./prebuilt-mk)

# _COCOS_LIB_IMPORT_ANDROID_BEGIN
# _COCOS_LIB_IMPORT_ANDROID_END

<cocos2dx 随记> 关于cocos2dx接Android sdk的一些坑

关于cocos2dx接Android sdk的一些坑

简单说说UI线程 :在Android中,有个非常重要的家伙非常霸道,那就是UI线程。这霸道之一:不能被阻塞。 之二:系统对每一个组件的调用都从UI线程分发出去。

简单说说openGL线程:但凡cocos2dx 启动的绘制线程都是openGL线程。就这么多


任何SDK界面的调用,必须从UI线程中调用,所以需要放到主线程中。如果我们直接从GL线程中调用,轻则调用不了,重者程序蹦死。

解决办法:

得到主线程的handler,这里简单说一种,就是在onCreate中new一个静态handler。

或者new Handler(Looper.getMainLooper()),且叫mainHandler吧,

启动一个线程,

[java] view plain copy
  1. ThreadsendThread=newThread(newRunnable(){
  2. publicvoidrun(){
  3. mainHandler.post(sendRun);
  4. }
  5. });

[html] copy

Android Cocos2dx-js 游戏 APP 逆向

Android Cocos2dx-js 游戏 APP 逆向

【直播预告】程序员逆袭 CEO 分几步?

1 Cocos2dx-js 资源文件

Cocos2dx-js 开发的游戏应用,其游戏核心内容被打包到了 Android 应用的 Assets 目录中。其中包含了经过加密的 jsc 文件,正因为经过加密处理,无法获取游戏核心逻辑。通常需要对 jsc 文件进行解密处理。Assets 目录结构如下图所示。

tree.png

2 获取 key

 

2.1 静态获取

静态方式直接使用 ida 打开 so 文件,以 jsb 和 encrypt 为关键字,可以定位到部分加密函数,其中 xxtea 系列函数尤为可以。尤其是 jsb_set_xxtea_key。xxtea.png函数 jsb_set_xxtea_key 看起来像是设置 key 的地方,F5 伪代码看下,传入了一个字符串化的指针参数,大概率可能是 Key。回溯调用该函数的地方,看下传入的参数值。最终在 applicationDidFinishLaunching 函数中找到了指针指向的字符串。applicationDidFinishLaunching.png

2.2 动态获取

根据上述静态获取方式的方法,同样可以使用 hook 的方式来取得 jsc 的加密 key。只需 hook jsb_set_xxtea_key 或者解密函数,然后获取该函数的参数即可。根据 so 和导出函数名可以快速写出 hook 脚本。

function hookJava() {
    Java.perform(function() {
        var Cocos2dxActivity = Java.use("org.cocos2dx.lib.Cocos2dxActivity")
        Cocos2dxActivity.onLoadNativeLibraries.implementation = function() {
            this.onLoadNativeLibraries()
            hookNative()
        }
    })
}

function hookNative() {
    Interceptor.attach(Module.findExportByName("libcocos2djs.so", "xxtea_decrypt"), {
        // 打印入参
        onEnter: function (args) {
            console.log("cocos key is : ", Memory.readUtf8String(args[2]));
        },
        // 打印返回值
        onLeave: function (returnValue) {

        }
    })
}
hookJava()

3 解密 jsc 文件

此处解密需要用到 jsc 解密工具,直接填入解密 key,拖入加密的 jsc 文件即可完成解密工作,之后就可以明文的方式浏览游戏逻辑。jscdecrypt.png

Android cocos2dx游戏开发——示例程序HelloCpp源码分析

Android cocos2dx游戏开发——示例程序HelloCpp源码分析

  本文通过分析cocos2dx提供的示例程序HelloCpp来分析cocos2dx的启动过程。

      我们从HelloCpp.java开始:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. package org.cocos2dx.hellocpp;  

  2.   

  3. import org.cocos2dx.lib.Cocos2dxActivity;  

  4.   

  5. import android.os.Bundle;  

  6.   

  7. public class HelloCpp extends Cocos2dxActivity{  

  8.   

  9.     protected void onCreate(Bundle savedInstanceState){  

  10.         super.onCreate(savedInstanceState);  

  11.     }  

  12.       

  13.     static {  

  14.          System.loadLibrary("hellocpp");  

  15.     }  

  16. }  

      HelloCpp是一个Activity,首先会执行静态代码块,加载libhellocpp.so库,然后就是执行onCreate方法,这里调用了父类的onCreate方法。我们看看Cocos2dxActivity的onCreate方法,该类在cocos2dx的库工程libcocos2dx中:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. @Override  

  2.     protected void onCreate(final Bundle savedInstanceState) {  

  3.         super.onCreate(savedInstanceState);  

  4.         sContext = this;  

  5.         this.mHandler = new Cocos2dxHandler(this);  

  6.   

  7.         this.init();  

  8.   

  9.         Cocos2dxHelper.init(thisthis);  

  10.     }  

      这里主要是执行初始化过程,Cocos2dxHandler主要处理显示Dialog的消息,Cocos2dxHelper是个辅助类,我们主要看init()方法:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. public void init() {  

  2.           

  3.         // FrameLayout  

  4.         ViewGroup.LayoutParams framelayout_params =  

  5.             new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,  

  6.                                        ViewGroup.LayoutParams.FILL_PARENT);  

  7.         FrameLayout framelayout = new FrameLayout(this);  

  8.         framelayout.setLayoutParams(framelayout_params);  

  9.   

  10.         // Cocos2dxEditText layout  

  11.         ViewGroup.LayoutParams edittext_layout_params =  

  12.             new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,  

  13.                                        ViewGroup.LayoutParams.WRAP_CONTENT);  

  14.         Cocos2dxEditText edittext = new Cocos2dxEditText(this);  

  15.         edittext.setLayoutParams(edittext_layout_params);  

  16.   

  17.         // ...add to FrameLayout  

  18.         framelayout.addView(edittext);  

  19.   

  20.         // Cocos2dxGLSurfaceView  

  21.         this.mGLSurfaceView = this.onCreateView();  

  22.   

  23.         // ...add to FrameLayout  

  24.         framelayout.addView(this.mGLSurfaceView);  

  25.   

  26.         // Switch to supported OpenGL (ARGB888) mode on emulator  

  27.         if (isAndroidEmulator())  

  28.            this.mGLSurfaceView.setEGLConfigChooser(8 , 888160);  

  29.   

  30.         this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());  

  31.         this.mGLSurfaceView.setCocos2dxEditText(edittext);  

  32.   

  33.         // Set framelayout as the content view  

  34.         setContentView(framelayout);  

  35.     }  

      这里就是为Activity绑定View Hierarchy,大家做Android开发的对着一定很熟悉。View Hierarchy的根View是个FrameLayout,FrameLayout又包含一个EditText和一个GLSurfaceView,这个GLSurfaceView就是cocos引擎用来绘制游戏画面的关键View,我们来详细分析一下它。首先看一下Cocos2dxActivity的onCreateView方法:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. public Cocos2dxGLSurfaceView onCreateView() {  

  2.         return new Cocos2dxGLSurfaceView(this);  

  3.     }  

      该方法就是新建一个Cocos2dxGLSurfaceView,Cocos2dxGLSurfaceView又继承于GLSurfaceView。我们都知道GLSurfaceView的核心就是Renderer,初始化时会调用Renderer的onSurfaceCreated方法,每一帧的绘制是通过调用Renderer的onDrawFrame方法。Cocos2dxGLSurfaceView的Renderer是一个Cocos2dxRenderer对象,我们先来看Cocos2dxRenderer对象的onSurfaceCreated方法:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. @Override  

  2.     public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) {  

  3.         Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);  

  4.         this.mLastTickInNanoSeconds = System.nanoTime();  

  5.     }  

      这里调用了一个本地方法nativeInit(final int pWidth, final int pHeight),本地方法的实现在jni/hellocpp/main.cpp中实现的:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)  

  2. {  

  3.     if (!CCDirector::sharedDirector()->getOpenGLView())  

  4.     {  

  5.         CCEGLView *view = CCEGLView::sharedOpenGLView();  

  6.         view->setFrameSize(w, h);  

  7.   

  8.         AppDelegate *pAppDelegate = new AppDelegate();  

  9.         CCApplication::sharedApplication()->run();  

  10.     }  

  11.     else  

  12.     {  

  13.         ......   

  14.     }  

  15. }  

      CCDirector是游戏的导演类,一个游戏只有一个导演类用来控制和管理场景。CCDirector::sharedDirector()是个静态方法,用来获取导演类的单例对象:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. CCDirector* CCDirector::sharedDirector(void)  

  2. {  

  3.     if (!s_SharedDirector)  

  4.     {  

  5.         s_SharedDirector = new CCDisplayLinkDirector();  

  6.         s_SharedDirector->init();  

  7.     }  

  8.   

  9.     return s_SharedDirector;  

  10. }  

      CCCCDisplayLinkDirector是CCDirector的子类。我们再回到nativeinit方法中,获取到导演类的单例对象后又调用了它的getOpenGLView()方法:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. inline CCEGLView* getOpenGLView(void) { return m_pobOpenGLView; }  

      该方法返回用于游戏绘制的CCEGLView,在Android平台下,这个CCEGLView其实没有什么作用,因为游戏都是绘制在Cocos2dxGLSurfaceView上的。由于我们是初始化过程,所以此时m_pobOpenGLView为null,所以if (!CCDirector::sharedDirector()->getOpenGLView())条件成立,执行以下的代码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. CCEGLView *view = CCEGLView::sharedOpenGLView();  

  2. view->setFrameSize(w, h);  

  3.   

  4. AppDelegate *pAppDelegate = new AppDelegate();  

  5. CCApplication::sharedApplication()->run();  

     同样,我们先获取一个CCEGLView的单例对象,接下来又新建了一个AppDelegate对象,大家可能在工程中找不到AppDelegate类。我们打开工程目录的上一级目录:
      我们的Android工程是在proj.android文件夹中,而AppDelegate类就在Classes文件夹中。因为cocos2dx是跨平台的,而AppDelegate在各个平台之间是通用的不需要修改的,所以就放在一个公用的目录下。

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. #ifndef  _APP_DELEGATE_H_  

  2. #define  _APP_DELEGATE_H_  

  3.   

  4. #include "cocos2d.h"  

  5.   

  6. /** 

  7. @brief    The cocos2d Application. 

  8.  

  9. The reason for implement as private inheritance is to hide some interface call by CCDirector. 

  10. */  

  11. class  AppDelegate : private cocos2d::CCApplication  

  12. {  

  13. public:  

  14.     AppDelegate();  

  15.     virtual ~AppDelegate();  

  16.   

  17.     /** 

  18.     @brief    Implement CCDirector and CCScene init code here. 

  19.     @return true    Initialize success, app continue. 

  20.     @return false   Initialize failed, app terminate. 

  21.     */  

  22.     virtual bool applicationDidFinishLaunching();  

  23.   

  24.     /** 

  25.     @brief  The function be called when the application enter background 

  26.     @param  the pointer of the application 

  27.     */  

  28.     virtual void applicationDidEnterBackground();  

  29.   

  30.     /** 

  31.     @brief  The function be called when the application enter foreground 

  32.     @param  the pointer of the application 

  33.     */  

  34.     virtual void applicationWillEnterForeground();  

  35. };  

  36.   

  37. #endif // _APP_DELEGATE_H_  

     AppDelegate是继承CCApplication类的,我们看一下CCApplication的构造方法:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. // sharedApplication pointer  

  2. CCApplication * CCApplication::sm_pSharedApplication = 0;  

  3.   

  4. CCApplication::CCApplication()  

  5. {  

  6.     CCAssert(! sm_pSharedApplication, "");  

  7.     sm_pSharedApplication = this;  

  8. }  

      我们看到在新建CCApplication对象时,会把该对象赋给一个全局变量sm_pSharedApplication。所以我们在new AppDelegate()的时候,就把它象赋给全局变量sm_pSharedApplication。我们再看下CCApplication的CCApplication::sharedApplication方法:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. CCApplication* CCApplication::sharedApplication()  

  2. {  

  3.     CCAssert(sm_pSharedApplication, "");  

  4.     return sm_pSharedApplication;  

  5. }  

      此时,sm_pSharedApplication指向的是一个AppDelegate对象。所以我们执行CCApplication::sharedApplication()->run()时其实执行的是AppDelegate对象的run方法。现在我们应该明白这个类为什么叫AppDelegate了,因为CCApplication的工作实际都委托给了AppDelegate类了。看一下AppDelegate的方法:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. int CCApplication::run()  

  2. {  

  3.     // Initialize instance and cocos2d.  

  4.     if (! applicationDidFinishLaunching())  

  5.     {  

  6.         return 0;  

  7.     }  

  8.       

  9.     return -1;  

  10. }  

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. bool AppDelegate::applicationDidFinishLaunching() {  

  2.     // initialize director  

  3.     CCDirector* pDirector = CCDirector::sharedDirector();  

  4.     CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();  

  5.   

  6.     pDirector->setOpenGLView(pEGLView);  

  7.     CCSize frameSize = pEGLView->getFrameSize();  

  8.   

  9.     // Set the design resolution  

  10. #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)  

  11.     pEGLView->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, kResolutionShowAll);  

  12. #else  

  13.     pEGLView->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, kResolutionNoBorder);  

  14. #endif  

  15.   

  16.       

  17.     vector<string> searchPath;  

  18.   

  19.     // In this demo, we select resource according to the frame''s height.  

  20.     // If the resource size is different from design resolution size, you need to set contentScaleFactor.  

  21.     // We use the ratio of resource''s height to the height of design resolution,  

  22.     // this can make sure that the resource''s height could fit for the height of design resolution.  

  23.   

  24.     // if the frame''s height is larger than the height of medium resource size, select large resource.  

  25.     if (frameSize.height > mediumResource.size.height)  

  26.     {  

  27.         searchPath.push_back(largeResource.directory);  

  28.   

  29.         pDirector->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height, largeResource.size.width/designResolutionSize.width));  

  30.     }  

  31.     // if the frame''s height is larger than the height of small resource size, select medium resource.  

  32.     else if (frameSize.height > smallResource.size.height)  

  33.     {  

  34.         searchPath.push_back(mediumResource.directory);  

  35.           

  36.         pDirector->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height, mediumResource.size.width/designResolutionSize.width));  

  37.     }  

  38.     // if the frame''s height is smaller than the height of medium resource size, select small resource.  

  39.     else  

  40.     {  

  41.         searchPath.push_back(smallResource.directory);  

  42.   

  43.         pDirector->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height, smallResource.size.width/designResolutionSize.width));  

  44.     }  

  45.   

  46.   

  47.     // set searching path  

  48.     CCFileUtils::sharedFileUtils()->setSearchPaths(searchPath);  

  49.       

  50.     // turn on display FPS  

  51.     pDirector->setDisplayStats(true);  

  52.   

  53.     // set FPS. the default value is 1.0/60 if you don''t call this  

  54.     pDirector->setAnimationInterval(1.0 / 60);  

  55.   

  56.     // create a scene. it''s an autorelease object  

  57.     CCScene *pScene = HelloWorld::scene();  

  58.   

  59.     // run  

  60.     pDirector->runWithScene(pScene);  

  61.   

  62.     return true;  

  63. }  





android-ndk – 从java(android)调用C(cocos2dx)方法进行我的应用内结算

android-ndk – 从java(android)调用C(cocos2dx)方法进行我的应用内结算

我正在尝试在我的cocos2dx- android项目中添加应用内结算.我可以通过jni从c类调用 java函数.

这是我通过jni调用我的java函数的方式.

JniMethodInfo t;
        JniHelper::getStaticmethodInfo(t,"com/test/project/Project","BuyProduct","(Ljava/lang/String;)V");

        char buffer[20];
        sprintf(buffer,"product1");
        jstring StringArg1 = t.env->NewStringUTF(buffer);

    t.env->CallStaticVoidMethod(t.classID,t.methodID,StringArg1);

应用内结算工作正常,但现在我必须给我的c类打电话,告知产品购买是否成功.

我只能通过提到指定的返回类型返回调用方法的结果,但是应用程序内进程是一个异步进程 – 经过大量的方法调用,我的控件不会返回到同一个方法.所以返回一个值是行不通的.

那么有没有其他方法将值(在我的情况下是应用程序内购买的结果)从java函数传递给我的c类???

解决方法

检查cocos2dxHelper.cpp文件,看看cocos2dx如何调用c方法.
基本上cocos2dxHelper.java中有一个方法只有定义而不是实现,通常它看起来像

public static native blahblah();

并且在cpp文件中有一个相应的函数被调用

Java_org_cocos2dx_cocos2dxHelper_blahblah()

如果你用runOnUIThread()调用Java代码中的blahblah(),那就是c函数

Java_org_cocos2dx_cocos2dxHelper_blahblah()

将被召唤.

顺便说一句,c代码需要在extern C {}中

关于cocos2dx 安卓makefile Android.mk,动态引用cpp地址cocos动态加载的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于 关于cocos2dx接Android sdk的一些坑、Android Cocos2dx-js 游戏 APP 逆向、Android cocos2dx游戏开发——示例程序HelloCpp源码分析、android-ndk – 从java(android)调用C(cocos2dx)方法进行我的应用内结算等相关知识的信息别忘了在本站进行查找喔。

本文标签: