讲讲c++如何统一不同平台的接口吧
c++如何调用objectC ios中 c++ 的文件可以用 .cpp 和 .mm 来结尾 区别是: .mm :带有这种扩展名的源代码文件,除了可以包含objective-c和C代码以外还可以包含C++代码。 .cpp:只能编译C++
所以,如果要从c++ 中调用 ios 底层的内容, .mm 文件必不可少。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 .h 文件 class TestFun { public: TestFun(); ~TestFun(); std::string getStrFromOC(); }; .mm 文件 TestFun::TestFun (){ cocos2d::log ("TestFun create" ); } TestFun::~TestFun (){ } // .mm 文件是可以直接调用 oc 中的方法的 std::string TestFun::getStrFromOC (){ return [[AppController myTestFun] UTF8String]; } //AppController.mm 文件添加内容 + (NSString *)myTestFun { return @"TestStr from AppController.h" ; } //调用部分在 AppDelegate LuaStack* stack = engine->getLuaStack(); stack->setXXTEAKeyAndSign("2dxLua" , strlen("2dxLua" ), "XXTEA" , strlen("XXTEA" )); auto testClass = new TestFun(); std::string str = testClass->getStrFromOC(); cocos2d::log ("fun call after is %s" ,str.c_str()); //打印 log TestFun create fun call after is TestStr from AppController.h [LUA-print] **********
由此可见 c++ 调用object-C 比较容易,更改后缀为.mm 就可以使用
c++如何调用java 既然是懒人,那就直接使用Test class 来做
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 .h 文件 class TestFun { public: TestFun(); ~TestFun(); std::string getStrFromOC(); //添加获取bunleId 的函数 std::string getBundleID(); }; .mm 文件 <!-- 添加新的函数 getBundleID--> std::string TestFun::getBundleID (){ std::string bundleId = "" ; <!-- 获取ios的上面已经写过了这里就不啰嗦了 --> bundleId = "" ; <!-- 添加宏 判断平台 --> <!-- 引入头java native interface 需要使用的文件 --> cocos2d::JniMethodInfo t; //jni 方法结构体 下面的使用需要这个结构体 if (cocos2d::JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lua/AppActivity" , "getBundleID" , "()Ljava/lang/String;" )){ <!-- getBundleID 传递参数为空 返回string 类型 --> jstring bundle = (jstring) t.env->CallStaticObjectMethod(t.classID, t.methodID); <!-- 需要把返回的jstring 转化为 string --> bundleId = cocos2d::JniHelper::jstring2string(bundle); } return bundleId; } <!-- 查看了下jni 的写法 --> typedef struct JniMethodInfo_ { JNIEnv * env; jclass classID; jmethodID methodID; } JniMethodInfo; 这个是jni 方法的结构体 getStaticMethodInfo 方法内容 1.判断是否传递参数 2.获取jni 环境 3.获取所要调用的class 的id 4.获取所需要调用静态函数的id 5.把所有的信息插入到结构体中 6.返回 true java文件 public static String getBundleID () { String packageName = "" ; try { // ---get the package info--- packageName = myContext.getPackageName(); if (packageName == null || packageName.length() <= 0) { return "" ; } } catch (Exception e) { Log.e("VersionInfo" , "Exception" , e); } return packageName; } c++调用部分 AppDelegate 文件 (不要忘记引用头文件) auto myClass = new TestFun(); std::string myStr = myClass->getBundleID(); cocos2d::log ("bundle id is %s" ,myStr.c_str()); Android.mk 文件 需要在 LOCAL_SRC_FILES 中添加 ../../Classes/Test.mm \ 执行编译 然而编译不过。。。 jni/../../Classes/AppDelegate.cpp:79: error: undefined reference to 'TestFun::TestFun()' jni/../../Classes/AppDelegate.cpp:80: error: undefined reference to 'TestFun::getBundleID()' jni/../../Classes/AppDelegate.cpp:83: error: undefined reference to 'TestFun::getStringWithParams()' collect2: error: ld returned 1 exit status 更改Test.mm 为 Test.cpp 更改Android.mk 文件中写入的为 ../../Classes/Test.cpp \ 再次编译,,过了 完美 D/cocos2d-x debug info( 1794): TestFun create D/cocos2d-x debug info( 1794): bundle id is org.cocos2dx.Hello adb logcat 中日志文件
上面我们写了一个获取java 字符串的函数,如果我们想向java 中传递函数呢 ? 接着来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 .h 文件 class TestFun { public: TestFun(); ~TestFun(); std::string getStrFromOC(); std::string getBundleID(); <!-- 添加传递参数的函数 --> std::string getStringWithParams(); }; .cpp 文件 <!-- 实现部分比上面多了 getStringWithParams --> std::string TestFun::getStringWithParams (){ std::string returnStr = "" ; cocos2d::JniMethodInfo t; if (cocos2d::JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lua/AppActivity" , "getMyString" , "(Ljava/lang/String;)Ljava/lang/String;" )){ cocos2d::log ("getStringWithParams from c++" ); <!-- 需要传递给java的字符串 --> std::string toJavaStr = "from c++ params" ; <!-- 需要转化为 jstring jni需要类型 --> jstring stringArg1 = t.env->NewStringUTF(toJavaStr.c_str()); <!-- CallStaticObjectMethod 函数 第三个是需要传递的数据 --> jstring myString = (jstring) t.env->CallStaticObjectMethod(t.classID, t.methodID,stringArg1); returnStr = cocos2d::JniHelper::jstring2string(myString); } return returnStr; } AppDelegate 文件中修改 auto myClass = new TestFun(); std::string myStr = myClass->getBundleID(); cocos2d::log ("bundle id is %s" ,myStr.c_str()); <!-- 新添加 getStringWithParams --> std::string returnStr = myClass->getStringWithParams(); cocos2d::log ("return str is %s" ,returnStr.c_str()); java 文件添加函数 public static String getMyString(String s) { Log.d("c++ call getMyString params is " ,s); return "return form java " ; } Android.mk 文件 依然依旧 ../../Classes/Test.cpp \ 编译通过 adb logcat c++ call getMyString params is ----> java 文件内容 std::string toJavaStr = "from c++ params" ; ----> c++文件传递给java D/c++ call getMyString params is ( 1794): from c++ params D/cocos2d-x debug info( 1794): return str is return form java
如上,通过.mm 文件可以直接调用oc 中函数,在cpp 文件中通过jni 可以调用java 也可以相互传递值
假如还想知道怎样从java 中调用c++ 该如何 ???好累,下次再写。。。