The general process of binding C + + with cocos2dx JS

Change from: https://www.jianshu.com/p/347feb55cee9

Cococs2dx JS version 3.12, environment: Mac
. There are two situations, one is to modify the engine's underlying methods and the other is to customize new C + + classes.

First of all, in order to ensure the normal operation of genbindings.py, you need to skip three things that have been installed

  1. python 2.7.x: Currently, the bindings generator in the engine only supports python 2.7.x version
  2. py-ymal(http://pyyaml.org/wiki/PyYAML ): This is a third-party package of python. The download page has different system installation methods. Please refer to generator.py This package will be called.
  3. cheetah(http://www.cheetahtemplate.org/ ): This is also a third-party package of python, a template, generator.py This package will be called

Execute python setup.py install in the installation directory to install

Modify engine underlying methods

This is relatively simple. What we do here is to add a public method to UIImageView. Then call this method with a UIImageView object in js.
First, add the following methods to UIImageView.cpp:

 

void ImageView::getImageDes()
{
    CCLOG("this is getImageDes!!");
}

Then go to the project / frameworks/cocos2d-x/tools/tojs directory to execute the python script genbindings.py. You can modify this script, and then just rebind the UIImageView related files. Then you can see the corresponding binding content in the JSB ﹣ cocos2d x ﹣ UI ﹣ auto.cpp file under the directory / frameworks / cocos2d-x / cocos / scripting / JS bindings / auto. As follows:

 

bool js_cocos2dx_ui_ImageView_getImageDes(JSContext *cx, uint32_t argc, jsval *vp)
{
    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    JS::RootedObject obj(cx, args.thisv().toObjectOrNull());
    js_proxy_t *proxy = jsb_get_js_proxy(obj);
    cocos2d::ui::ImageView* cobj = (cocos2d::ui::ImageView *)(proxy ? proxy->ptr : NULL);
    JSB_PRECONDITION2( cobj, cx, false, "js_cocos2dx_ui_ImageView_getImageDes : Invalid Native Object");
    if (argc == 0) {
        cobj->getImageDes();
        args.rval().setUndefined();
        return true;
    }

    JS_ReportError(cx, "js_cocos2dx_ui_ImageView_getImageDes : wrong number of arguments: %d, was expecting %d", argc, 0);
    return false;
}

Then you can call the getImageDes method in the js script, as follows:

 

this._image.getImageDes();

The console can see the print. This is a simple binding.

Add custom C + + classes

Here I create a simple C + + class, CustomClass:
CustomClass.h

 

#ifndef CUSTOMCLASS
#define CUSTOMCLASS
#include "cocos2d.h"
namespace cocos2d {
  class CustomClass : public cocos2d::Ref
  {
    public:
      CustomClass();
      ~CustomClass();
      bool init();
      std::string helloMsg();
      CREATE_FUNC(CustomClass);
  };
} //namespace cocos2d
#endif // CUSTOMCLASS

CustomClass.cpp

 

#include "CustomClass.h"
USING_NS_CC;
CustomClass::CustomClass(){
}
CustomClass::~CustomClass(){
}
bool CustomClass::init(){
  return true;
}
std::string CustomClass::helloMsg(){
  return "this is CustomClass Msg!";
}

Then put this class in the game engineering directory / frameworks/cocos2d-x/cocos/my /.

 

file.png

 

Then import my folder into cocos2d? LIBS project,

 

structure.png

And for User Header Searcher Paths of cocos2d ﹣ LIBS project, add a directory and specify it to my directory, $(srcroot) /.. /.. / cocos / my.

add_header_search_path.png

 

At the same time, I also added this directory to the game project (this is unnecessary).
Then add the cocos2dx [custom.ini] file under the tojs folder. This can be copied, and then the corresponding location can be modified, mainly
Headers =% (cocosdir) s / cocos / my / customclass. H this is the path of the header file, and then
classes = CustomClass. * this is the class to include
Classes \ need \ extend = classes that need to be derived in js

Then modify the file genbindings.py, line 151, and add the cocos2dx_custom.init file just now, as follows:

 

cmd_args = {'cocos2dx.ini': ('cocos2d-x', 'jsb_cocos2dx_auto'),
            'cocos2dx_custom.ini': ('cocos2dx_custom', 'jsb_cocos2dx_custom_auto'),
            }

This is a complete cocos2dx [custom.ini:

 

[cocos2dx_custom]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_custom

# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = ccext

android_headers = -I%(androidndkdir)s/platforms/android-19/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include
android_flags = -D_SIZE_T_DEFINED_ 

clang_headers = -I%(clangllvmdir)s/lib/clang/%(clang_version)s/include 
clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__


cocos_headers = -I%(cocosdir)s -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/platform/android -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/network -I%(cocosdir)s/cocos/ui/UIEditBox -I%(cocosdir)s/cocos/ui -I%(cocosdir)s/jsext -I%(cocosdir)s/jsext/system -I%(cocosdir)s/jsext/alipay  -I%(cocosdir)s/jsext/video -I%(cocosdir)s/jsext/webview -I%(cocosdir)s/jsext/umeng
#cocos_headers = -I%(cocosdir)s -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android

cocos_flags = -DANDROID

cxxgenerator_headers = 

# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s 

# what headers to parse header file path
headers = %(cocosdir)s/cocos/extra/CustomClass.h

# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
#Included classes, new added files need to be modified
classes = CustomClass.*

#Classes that need to be derived in js
#classes_need_extend = CustomClass

# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.

skip = 

rename_functions = 

rename_classes = 

# for all class names, should we remove something when registering in the target VM?
remove_prefix = 

# classes for which there will be no "parent" lookup
classes_have_no_parents = 

# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip = Ref

# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes = 

# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = no

The rest is to run python genbindings.py. After the binding is successful, you can see the corresponding JSB ﹣ cocos2d x ﹣ custom ﹣ auto.hpp and JSB ﹣ cocos2dx ﹣ custom ﹣ auto.cpp in the project / frameworks / cocos2d-x / cocos / scripting / JS bindings / Auto directory. At the same time, there is an API folder in this directory, and JSB ﹣ cocos2dx ﹣ custom ﹣ api.js is generated accordingly.
Then import these two files into the auto folder of cocos2d? JS? Bindings project.

 

jsb_binding_structure.png

Then register in AppDelegate.cpp file as follows:

 

//jsbinding test
sc->addRegisterCallback(register_all_cocos2dx_custom);

Then we can use our C + + classes in js code

 

var customClass = ccext.CustomClass.create();
var msg = customClass.helloMsg()
cc.log("customClass's msg is========>>>" + msg)

At this time, you can see the print log in the console. So far, js binding to C + + has been completed.

And then there's Android. It is mainly to include our newly added classes into Android.mk. First, go to the project / frameworks / cocos2d-x / cocos / scripting / JS bindings / proj. Android / directory, find Android.mk, and then under LOCAL_C_INCLUDES, include the path of our newly added class. Under local SRC files, our cpp file is as follows:.. / Auto / JSB ﹣ cocos2dx ﹣ custom ﹣ auto. CPP \. At the same time, we should ensure that our original C + + classes are also included in the MK file, so that we can find our original C + + files when mutating. Then there's no problem compiling Android.



Author: salted fish
Link: https://www.jianshu.com/p/347feb55cee9
Source: Jianshu
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

227 original articles published, 231 praised, 1.68 million visitors+
His message board follow

Tags: Android Python Mac Javascript

Posted on Wed, 05 Feb 2020 07:24:04 -0500 by sunnyk