Cocos2d-x Js Binding 的手动绑定实现

2023-11-09

http://www.ityran.com/archives/4902

Cocos2d-x Js Binding 的手动绑定实现

一叶  cocos2d-x  08-13  2304  4条评论

随着 Cocos2d-x 的发展,Cocos2d-html5 也日益完善,相比纯 C++ 的开发方式,它开发效率更为高效,而另一个显而易见的好处便是 JS 端的 API 可以作为 Cocos2d-x Javascript Bindings (JSB) 的接口封装。一套 API,两种解决方案,这让用 JS 快速开发游戏,通过 JSB 以接近原生代码的速度来运行游戏成为可能。

这里使用当前稳定版 Cocos2d-x-2.1.4,Xcode JSB 项目模板创建项目,如果是用其它 IDE ,注意配置好不同环境的依赖关系,本文的示例源码可以在 【这里】 看到。

JSB 手动绑定的实现步骤

要实现 C++ 到 JS 的手动绑定,首先我们需要定义一个待绑定的类,为了这里的解说简单,创建了一个非常简单的类,也只定义了些简单的方法,如下:

   
   
  1. // Leafsoar.h 文件定义
  2. namespace ls {
  3.  class Leafsoar: public cocos2d::CCObject
  4.  {
  5.  public:
  6.  static cocos2d::CCScene* scene();
  7.  virtual bool init();
  8. CREATE_FUNC(Leafsoar);
  9.  void functionTest();
  10.  };
  11. }
  12.  
  13. // Leafsoar.cpp 实现
  14. bool ls::Leafsoar::init(){
  15.  bool bRef = false;
  16.  do {
  17. cocos2d::CCLog("leafsoar init ...");
  18. bRef = true;
  19.  } while (0);
  20.  return bRef;
  21. }
  22. void ls::Leafsoar::functionTest(){
  23. cocos2d::CCLog("function Test");
  24. }

以上是我们定义的一个类,在 ls 命名空间里面,它很简单,继承自 CCObject,定义实现了 functionTest 方法,我们下面要做的就是将它绑定到 JS ,最终达到通过 JS 来创建对象,并且调用方法。如果不知道从何下手,那么下面是一种实现思路。

为了使代码风格统一 (这样的好处是任何人都能相对容易的读懂代码并修改之),我们将参照 Cocos2d-x 现有的 JSB 实现,如从 AppDelegate 的 applicationDidFinishLaunching 方法开始,里面实现了 JSB 环境的初始化等操作,其中我们看到类似 sc->addRegisterCallback(register_all_cocos2dx); 这样的代码,而我们将创建 register_all_ls 方法,来完成我们自有 ls 命名空间下需要绑定的代码。

编写 jsb_ls_auto.h 文件,定义如下:

   
   
  1. #include "jsapi.h"
  2. #include "jsfriendapi.h"
  3. #include "ScriptingCore.h"
  4.  
  5. void register_all_ls(JSContext* cx, JSObject* obj);

完成了以上 register_all_ls 方法定义,它作为自定义 JSB 手动绑定函数的入口,内中实现绑定我么的命名空间,我们的类和方法等 ~ 所以 js_ls_auto.cpp 的实现需要根据自己的需要实现,以下是当前的实现步骤,:

   
   
  1. #include "jsb_ls_auto.h"
  2. #include "cocos2d.h"
  3. #include "Leafsoar.h"
  4.  
  5. #include "cocos2d_specifics.hpp"
  6.  
  7. // 定义 js 端的类型
  8. JSClass *jsb_LsLeafsoar_class;
  9. JSObject *jsb_LsLeafsoar_prototype;
  10.  
  11. // 实现 ls 命名空间下的类绑定
  12. void register_all_ls(JSContext* cx, JSObject* obj) {
  13. jsval nsval;
  14.  JSObject *ns;
  15. JS_GetProperty(cx, obj, "ls", &nsval);
  16.  if (nsval == JSVAL_VOID) {
  17. ns = JS_NewObject(cx, NULL, NULL, NULL);
  18. nsval = OBJECT_TO_JSVAL(ns);
  19. JS_SetProperty(cx, obj, "ls", &nsval);
  20.  } else {
  21. JS_ValueToObject(cx, nsval, &ns);
  22.  }
  23. obj = ns;
  24.  
  25.  // 实现绑定 Leafsoar 类,它的定义后文给出
  26. js_register_ls_Leafsoar(cx, obj);
  27. }

为了实现思路的清晰,所以文章内容以 register_all_ls 为入口,一步步实现,需要什么,我们就去实现什么,看到上面绑定了命名空间(在 js 中并没有明确的命名空间的机制,但 js 能实现类似命名空间的效果),并调用了js_register_ls_Leafsoar(cx, obj); 方法来实现具体的绑定,下面是它的实现:

   
   
  1. // 绑定 Leafsoar 类的实现
  2. void js_register_ls_Leafsoar(JSContext *cx, JSObject *global) {
  3.  // 创建一个 JS 类型的对象
  4. jsb_LsLeafsoar_class = (JSClass *)calloc(1, sizeof(JSClass));
  5.  // 类型名称为 **Leafsoar** 正式绑定到 js 由 js 调用的名称
  6. jsb_LsLeafsoar_class->name = "Leafsoar";
  7. jsb_LsLeafsoar_class->addProperty = JS_PropertyStub;
  8. jsb_LsLeafsoar_class->delProperty = JS_PropertyStub;
  9. jsb_LsLeafsoar_class->getProperty = JS_PropertyStub;
  10. jsb_LsLeafsoar_class->setProperty = JS_StrictPropertyStub;
  11. jsb_LsLeafsoar_class->enumerate = JS_EnumerateStub;
  12. jsb_LsLeafsoar_class->resolve = JS_ResolveStub;
  13. jsb_LsLeafsoar_class->convert = JS_ConvertStub;
  14.  // Leafsoar 类型的析构函数绑定
  15. jsb_LsLeafsoar_class->finalize = js_ls_Leafsoar_finalize;
  16. jsb_LsLeafsoar_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
  17.  
  18.  static JSPropertySpec properties[] = {
  19.  {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}
  20.  };
  21.  
  22.  // 为 Leafsoar 设定绑定函数,函数名 "functionTest",绑定函数 "js_ls_Leafsoar_functionTest"
  23.  // 后面可以添加其它函数绑定,如果需要,之后以 "JS_FS_END" 结尾
  24.  static JSFunctionSpec funcs[] = {
  25. JS_FN("functionTest", js_ls_Leafsoar_functionTest, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),
  26. JS_FS_END
  27.  };
  28.  
  29.  // 这里定义并且绑定了静态函数(static),包括方法名 "create" 和对应的绑定实现 "js_ls_Leafsoar_create"
  30.  static JSFunctionSpec st_funcs[] = {
  31. JS_FN("create", js_ls_Leafsoar_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
  32. JS_FS_END
  33.  };
  34.  
  35.  // 初始化类型属性
  36. jsb_LsLeafsoar_prototype = JS_InitClass(
  37. cx, global,
  38. NULL, // parent proto
  39. jsb_LsLeafsoar_class,
  40. js_ls_Leafsoar_constructor, 0, // 这里绑定的是构造函数的实现,也就是用 js new 操作符创建的对象
  41. properties,
  42. funcs, // 函数绑定
  43. NULL, // no static properties
  44. st_funcs); // 静态函数绑定
  45.  
  46.  JSBool found;
  47. JS_SetPropertyAttributes(cx, global, "Leafsoar", JSPROP_ENUMERATE | JSPROP_READONLY, &found);
  48.  
  49.  TypeTest<ls::Leafsoar> t;
  50.  js_type_class_t *p;
  51.  uint32_t typeId = t.s_id();
  52. HASH_FIND_INT(_js_global_type_ht, &typeId, p);
  53.  if (!p) {
  54. = (js_type_class_t *)malloc(sizeof(js_type_class_t));
  55. p->type = typeId;
  56. p->jsclass = jsb_LsLeafsoar_class;
  57. p->proto = jsb_LsLeafsoar_prototype;
  58. p->parentProto = NULL;
  59. HASH_ADD_INT(_js_global_type_ht, type, p);
  60.  }
  61. }

写到这里,类型的绑定已经基本完成,但是可以看见,其中所用到的如 js_ls_Leafsoar_functionTestjs_ls_Leafsoar_finalize 、js_ls_Leafsoar_create 和 js_ls_Leafsoar_constructor 并没有实现,它们是在绑定 Leafosar 类型的时候去绑定了,所以需要在调用前去实现它们,下面是它们的实现:

   
   
  1. // js 端 functionTest 所绑定的方法调用
  2. JSBool js_ls_Leafsoar_functionTest(JSContext *cx, uint32_t argc, jsval *vp)
  3. {
  4.  JSBool ok = JS_TRUE;
  5.  
  6.  JSObject *obj = NULL;
  7. ls::Leafsoar* cobj = NULL; // 定义以获取真实类型
  8. obj = JS_THIS_OBJECT(cx, vp);
  9.  js_proxy_t *proxy = jsb_get_js_proxy(obj);
  10.  // 获取 js 绑定的实际对象 通过 proxy->ptr
  11. cobj = (ls::Leafsoar *)(proxy ? proxy->ptr : NULL);
  12. JSB_PRECONDITION2( cobj, cx, JS_FALSE, "Invalid Native Object");
  13.  if (argc == 0) {
  14.  // 调用实际的方法
  15. cobj->functionTest();
  16. JS_SET_RVAL(cx, vp, JSVAL_VOID);
  17.  return ok;
  18.  }
  19.  
  20. JS_ReportError(cx, "wrong number of arguments");
  21.  return JS_FALSE;
  22. }
  23.  
  24. // js 构造函数实现
  25. JSBool js_ls_Leafsoar_constructor(JSContext *cx, uint32_t argc, jsval *vp)
  26. {
  27. cocos2d::CCLog("js ls lsleafsoar constructor ..");
  28.  if (argc == 0) {
  29.  // 调用 C++ 构造函数
  30. ls::Leafsoar* cobj = new ls::Leafsoar();
  31. cocos2d::CCObject* _ccobj = dynamic_cast<cocos2d::CCObject*>(cobj);
  32.  // 默认使用原有的内存管理方式
  33.  if (_ccobj){
  34. _ccobj->autorelease();
  35.  }
  36.  TypeTest<ls::Leafsoar> t;
  37.  js_type_class_t *typeClass;
  38.  uint32_t typeId = t.s_id();
  39. HASH_FIND_INT(_js_global_type_ht, &typeId, typeClass);
  40.  assert(typeClass);
  41.  JSObject *obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);
  42. JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
  43.  // 构造 js 端对象,将 cobj 实际对象存入
  44.  js_proxy_t* p = jsb_new_proxy(cobj, obj);
  45. JS_AddNamedObjectRoot(cx, &p->obj, "ls::Leafsoar");
  46.  
  47.  return JS_TRUE;
  48.  }
  49.  
  50. JS_ReportError(cx, "wrong number of arguments: %d, was expecting %d", argc, 0);
  51.  return JS_FALSE;
  52. }
  53.  
  54. // 静态函数 create 的具体实现
  55. JSBool js_ls_Leafsoar_create(JSContext *cx, uint32_t argc, jsval *vp)
  56. {
  57. cocos2d::CCLog("js ls lsleafsoar create ..");
  58.  if (argc == 0) {
  59.  // 创建 Leafsoar 对象
  60. ls::Leafsoar* ret = ls::Leafsoar::create();
  61. jsval jsret;
  62.  do {
  63.  if (ret) {
  64.  js_proxy_t *proxy = js_get_or_create_proxy<ls::Leafsoar>(cx, ret);
  65. jsret = OBJECT_TO_JSVAL(proxy->obj);
  66.  } else {
  67. jsret = JSVAL_NULL;
  68.  }
  69.  } while (0);
  70. JS_SET_RVAL(cx, vp, jsret);
  71.  return JS_TRUE;
  72.  }
  73. JS_ReportError(cx, "wrong number of arguments");
  74.  return JS_FALSE;
  75. }
  76.  
  77. void js_ls_Leafsoar_finalize(JSFreeOp *fop, JSObject *obj) {
  78.  // 析构函数实现,如果在构造函数做了什么,如开辟内存空间,那么需要在这里做些收尾工作
  79.  // CCLOGINFO("jsbindings: finalizing JS object %p (LsLeafsoar)", obj);
  80. }

通过以上的步骤,我们实现了 C++ 类 Leafosar 到 JS 端的绑定。在 JS 中我们可以通过以下调试测试:

   
   
  1. // var ls = new ls.Leafsoar();
  2. // 或者
  3. var ls = ls.Leafsoar.create();
  4. // 之后调用
  5. ls.functionTest();

怎样实现 C++ 回调 JS

在上文,完成了 C++ 到 js 的手动绑定,但有时我们还需要其它一些功能,比如想在 C++ 开一个多线程以加载资源,或者一个网络异步请求,再如要实现一个 delegate 以实现接口回调,然这些都归为同一个问题,实现 C++ 到 js 的回调。我们在 js 端定义了一个 Leafsoar 对象,并且新实现了一个方法,等待 C++ 端的回调,如下:

   
   
  1. var ls = new ls.Leafsoar(); // 创建一个对象
  2. // 定义回调函数 callback
  3. ls.callback = function(i, j){
  4. log("ls.callback " + i + j);
  5. };
  6. ls.functionTest();

我们想通过调用 functionTest 之后回调在 js 端定义的 callback 方法。那么我们需要重新实现 C++ 端的 functionTest 方法:

   
   
  1. void ls::Leafsoar::functionTest(){
  2. cocos2d::CCLog("function Test");
  3.  js_proxy_t * p = jsb_get_native_proxy(this);
  4. jsval retval;
  5.  JSContext* jc = ScriptingCore::getInstance()->getGlobalContext();
  6.  // 定义参数,由两个参数
  7. jsval v[] = {
  8. v[0] = int32_to_jsval(jc, 32),
  9. v[1] =UINT_TO_JSVAL(88)
  10.  };
  11.  // 通过 ScriptingCore 封装好的方法实现回调,可以帮助我们节省很多细节上的研究
  12.  ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj), "callback", 2, v, &retval);
  13. }

JSB 的内存管理

了解 Cocos2d-x 的朋友知道,它的内存管理方式,如果对此有疑问,可以参见 Cocos2d-x 内存管理浅说 和 深入理解 Cocos2d-x 内存管理 这两篇文章,那么在 JSB 我们如何来管理内存呢?在 C++ 需要通过 retain 和 release 来实现引用计数的管理(源码示例也给出它的绑定实现,但仅仅作为参考),在绑定 js 时,如果不做相应处理,那么可能会出现 js 正在运行着的代码,所绑定的实际 C++ 对象已经释放。虽然我们能通过 绑定实现 retain 和 release 方法,来实现 js 端的此方法调用,但这显然不符合 js 代码边的习惯,它是自动回收的,所以这里推荐 始终 由 SpiderMonkey 来保持一份对象引用,以使它更像 JS 的使用方式,当 js 垃圾回收自动执行时,在去释放 SpiderMonkey 对对象的引用。

要做到这一点,我们需要只要修改上文的代码实现,在 构造函数,create 静态方法,实现对 C++ 类型对象的引用,在 析构绑定的析构函数中解除对其的引用以完成 C++ 到 JS 端绑定的内存管理方案。

本文出自:http://www.ityran.com/archives/4902

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cocos2d-x Js Binding 的手动绑定实现 的相关文章

  • cocos2dx-lua开发旅程(一)

    最近要做一个手游项目 打算用cocos2dx来做 我也是初学者 网上很多书籍和资料都是采用cocos2dx的c 版本来做开发示例的 很少关于cocos2dx和lua怎么结合在实际项目中的教程 这使得我很痛苦 所以我写下这一系列教程 希望跟我
  • mesa图解

    http www sourcecodebrowser com mesa 7 8 2 state 8c html
  • 使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景

    原文地址 http article ityran com archives 2140 本为由泰然教程组成员 浅底 原创 作为一位经验丰富的游戏开发人员 这次浅底将CocosBuilder经验分享给大家 希望大家喜欢 欢迎拍砖 转载请注明出处
  • Cocos2d-x 3.x部署

    这是我第一次写技术文章 这里只是分享一下我的部署经验 请各位参考 谢谢 我简单的写写我的部署步骤 只参考了官方的readme 环境 win7 64位 1 打开控制台cmd 2 进入到cocos2d x引擎目录 键入setup py 键入的前
  • Cocos2dx中文乱码问题

    最开始在网上找的一个方法 结果在wp8上报错 在windows环境下使用visual studio 开发cocos2d x 由于visual studio 默认编码为GBK 格式 而cocos2d x引擎默认编码为UTF 8 如果有用到中文
  • android Intent启动flag

    android Intent启动flag 分类 android框架 2013 10 30 14 47 1318人阅读 评论 0 收藏 举报 FLAG GRANT READ URI PERMISSION 如果设置这个标记 Intent的接受者
  • cocos2d-x实例学习(8)之CCJumpTo和CCJumpBy

    CCJumpTo和CCJumpBy概念 CCJumpTo 把某一CCSprite跳到某一位置 CCJumpBy 把某一CCSprite跳起一段距离 它有一个方法reverse 它让对象按原路径返回 CCJumpTo和CCJumpBy示例 创
  • Cocos2dx-OpenGL ES2.0教程:编写自己的shader(2)

    在上篇文章中 我给大家介绍了如何在cocos2d x里面绘制一个三角形 当时我们使用的是cocos2d x引擎自带的shader和一些辅助函数 在本文中 我将演示一下如何编写自己的shader 同时 我们还会介绍VBO 顶点缓冲区对象 和V
  • Box2D C++ 教程-查询 World

    声明 本文翻译自Box2D C tutorial World querying 仅供学习参考 查询World 通常你可能想知道在给定的场景中都有哪些实体 例如有一个炸弹爆炸了 周围的所有实物都会受到不同程度的破坏 那么在RTS 译者注 Re
  • 环境搭建Cocos2d-x学习之创建Android工程和编译

    http www cnblogs com lhming archive 2012 06 27 2566467 html 安装好 相应的环境之后 我们便可以开始创建cocos2d x 的android 工程了 进入cocs2d x目录 用文本
  • COCOS2DX学习之Box2D物理引擎-------物体和相互作用

    1 创建一个静态物体 创建一个静态物体应该很简单 在头文件生命一下要创建新物体的函数 然后在cpp文件中实现它即可 具体的时候先过程 首先要用createbody函数创建一个物体 然后定义一个b2bodydef变量 指定一下这个变量的typ
  • Android.mk - 构建目录中的所有源文件

    我正在使用 Android NDK 构建我的 cocos2dx 项目 在 Android mk 中 有一个 LOCAL SRC FILES 的定义 其中列出了每个 cpp 文件 每当我添加新的源文件时 我也需要将它添加到那里 它看起来像这样
  • Cocos2D-x 3.0 中图元和精灵的 Z 索引不一致?

    我有两层 每个图层都有一个使用 OpenGL 进行的原始绘图 如下所示 void Layer1 drawPolygon glLineWidth 1 DrawPrimitives setDrawColor4B 255 255 255 255
  • SSL 归档符号表错误(运行 ranlib)

    我构建了 OpenSS1 0 2g智能狐客户端 http smartfoxserver com API 1 6 3 Cocos2dx v3 Android Windows 10 64 位 它抛出错误 SSL 归档符号表错误 运行 ranli
  • Android 游戏的 Cocos2d-x 与 cocos2d-android

    在我的一个项目中使用 cocos2d iphone 后 我试图决定应该在 Android 游戏中使用哪种风格的 Cocos2d 我个人的优点和缺点清单 Cocos2d x pros 稍后将游戏带到 iOS 上应该会更容易 其他平台也可能如此
  • Cocos2d-x - 如何将CCLayer的一部分设置为透明?

    我是新手cocos2d x我需要你的帮助 我需要使图层的触摸部分透明 如何使图层的一部分透明 我曾想过使用 ClippingNode 但我找不到示例或文档 我使用C 谢谢 在所有cocos2d x版本中添加的TestCpp项目中 您可以找到
  • 由于资源文件权限被拒绝,Cocos2D-x HelloCpp for Android 无法从 Windows 构建 apk

    我试图在 Android 上运行 cocos2dx HelloCpp 示例项目 从 Windows 7 64 位和 Cygwin 64 位构建 但是 每次我尝试构建和运行时 它都会抱怨资产中的 Marker Felt fnt 文件的权限被拒
  • 使用GL着色器语言的相机帧yuv到rgb转换

    我从字节数组中的 android 相机预览回调获取相机帧并将其传递给 jni 代码 由于我们不能在 C 中使用字节 因此我将其转换为整数数组 如下所示 JNIEXPORT void JNICALL Java com omobio armad
  • Cocos2d-x:可以使用HTML(UIWebView)吗?

    我正在尝试cocos2d x现在我可以为 Android 构建 Javascript 示例并在浏览器中运行它们 现在我想创建自己的游戏 但由于有 HTML 背景 我宁愿使用 HTML 标签和 CSS 也不愿使用 Javascript 来设置
  • 安卓后退按钮不起作用

    我正在使用 cocos2dx 制作一个小游戏 在游戏的活动中我提供以下函数来处理后退按钮 Override public boolean onKeyDown int keyCode KeyEvent event return super o

随机推荐

  • 使用frp进行内网穿透

    frp概述 frp 是一个高性能的反向代理应用 可以帮助您轻松地进行内网穿透 对外网提供服务 支持 tcp http https 等协议类型 并且 web 服务支持根据域名进行路由转发 frp 采用 C S 模式 将服务端部署在具有公网 I
  • 科学数学工程工具MATLAB软件2023a中文版下载安装,MATLAB特色

    MATLAB软件是一款被广泛应用于科学计算和工程设计领域的软件 其独特的功能使其成为了许多行业专业人员的首选 下面将会介绍MATLAB软件的独特功能并举例说明其在实际应用中的作用 MATLAB信号处理功能 MATLAB获取 hairuank
  • 【资源共享】好用的视觉软件Adaptive Vision Studio

    TRITOP Professional 2018 TRITOPBasic2018 PONTOS Live 2018 GOM Scan 2018 GOM Inspect Professional 2018 ATOS Professional
  • 【语义分割】分层多尺度注意力 Hierarchical multi-scale attention for semantic segmentation

    文章目录 1 摘要 2 引言 3 本文相关方法 3 1 Multi scale context methods 3 2 Relational context methods 3 3 Multi scale inference 3 4 Aut
  • 显式内存管理

    程序员在处理现实生活中国的C C 程序的时候 常会遇到诸如程序运行时突然退出 或占用的内存越来越多 最后不得不定期重启的一些典型状况 这些问题的源头可以追溯到C C 中的显式堆内存管理上 通常情况下 这些症状都是由于程序没有正确处理堆内存的
  • tomcat 乱码问题

    测试环境 apache tomcat 6 0 48 操作系统 win7 中文 默认GBK编码 一 浏览器采用的字符集 测试jsp
  • docker容器监控系统

    文章目录 第1章监控软件介绍 1 1监控工具 第2章Cadvisor Influxdb Grafana 2 1Cadvisor InfluxDB Grafana介绍 2 1 1Cadvisor 数据采集 2 1 2InfluxDB 数据存储
  • F - Ginger的GIAO

    F Ginger的GIAO SDUT OnlineJudge include
  • GDB调试动态库

    转载 https blog csdn net huluedeai article details 52225923 一 方法 gdb如何调试动态链接库的问题 比如我想调试的代码为动态链接库代码 我设置断点后却得到以下错误 gdb b mps
  • 你从未见过的python重点知识总结,最全面没有之一。过了这村就没这店了。

    强烈建议收藏再慢慢看 Py2 VS Py3 Py2 和 Py3 的差别 print 成为了函数 python2 是关键字 不再有 unicode 对象 默认 str 就是 unicode python3 除号返回浮点数 没有了long类型
  • 波士顿房价预测(终版讲解)

    代码段分四个部分 库的引入 加载数据 函数 配置网络结构 类 运行部分 获取数据 创建网络 启动训练 作图 我的是基础版 库只用到了numpy和matplotlib的pyplto两个 加载数据需要进行将数据作为数组输入 重整成14 N的二维
  • Mybatis PageHelper(MyBatis 分页插件 )的使用

    概述 如果你也在用 MyBatis 建议尝试该分页插件 这一定是最方便使用的分页插件 分页插件支持任何复杂的单表 多表分页 我们在项目中使用sql的手动分页太常见了 如果前台需要分页信息的话 一般我们是需要2条slq语句 一条是查询总页数c
  • leetcode刷题-代码训练营-第3章-哈希表

    目录 242 有效的字母异位词 349 两个数组的交集 202 快乐数 1 两数之和 454 四数相加II 383 赎金信 1 暴力解法 2 哈希表解法 15 三数之和 1 哈希解法 2 双指针法 18 四数之和 242 有效的字母异位词
  • Java 微服务框架选型(Dubbo 和 Spring Cloud?)

    微服务 Microservices 是一种架构风格 一个大型复杂软件应用由一个或多个微服务组成 系统中的各个微服务可被独立部署 各个微服务之间是松耦合的 每个微服务仅关注于完成一件任务并很好地完成该任务 在所有情况下 每个任务代表着一个小的
  • 【常见错误】FPGA器件DDR类型选择错误

    ZedBoard开发常见错误 DDR的型号配置错误 间接会导致的结果是 在调试debug时 会发现cpu一直处于running的状态 但是在控制台并不能看到打印的信息 并且不管是只用了PS端或者是PS PL端都用了 都不能在控制台上出现打印
  • 短信验证码

    短信验证码用的是阿里云的 目录结构如下 其中aliyunsdkdysmsapi是在官方下载的 https help aliyun com document detail 55359 html aliyun py coding utf 8 i
  • 注入技术--LSP劫持注入

    1 原理 简单来说 LSP就是一个dll程序 应用程序通过winsock2进行网络通信时 会调用ws2 32 dll的导出函数 如connect accept等 而后端通过LSP实现这些函数的底层 简单来说就是调用winsock2提供的函数
  • 硬件系统工程师宝典(13)-----PCB的布局“有讲究”

    各位同学大家好 欢迎继续做客电子工程学习圈 今天我们继续来讲这本书 硬件系统工程师宝典 上篇我们说到EMC的标准以及提高EMC性能的一些常用方法 今天我们来看看PCB上模块的布局有什么讲究 模块划分及布局 PCB上模块的划分和布局会影响到布
  • Linux  root密码忘记了,怎么办?

    Linux root用户密码忘记了 怎么办 一 清除密码 首先 启动Linux 出现这个画面 有的版本不一定 和这个 一样但是大同小异 注意这句话就行 Press any key to enter the menu 按任意键进入菜单 然后
  • Cocos2d-x Js Binding 的手动绑定实现

    http www ityran com archives 4902 Cocos2d x Js Binding 的手动绑定实现 一叶 cocos2d x 08 13 2304 4条评论 随着 Cocos2d x 的发展 Cocos2d htm