如何
为什么
时间
调用者须知
|
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
|
#define CCX_BREAK_IF(cond) if(cond) break;#define CCX_SAFE_DELETE(p) if(p) {delete (p); (p) = NULL;}// declarationclass CCar{public: CCar(); bool init(); virtual ~CCar();protected: CEngine* m_pEngine; bool m_bStarted; bool m_bLocked;};// 1st-phase construction// only set the default value & alloc memoryCCar::CCar():m_pEngine(new CEngine),m_bStarted(false),m_bLocked(true){ printf("CCar constructor\n");}// 2st-phase construction// do logical initializationbool CCar::init(){ bool bRet = false; do { m_bLocked = false; CCX_BREAK_IF( !m_pEngine ); // defensive CCX_BREAK_IF( !m_pEngine->start() ); // logic // success bRet = true; } while(0); printf("CCar init\n"); return bRet;}// destructionCCar::~CCar(){ if (m_pEngine) { delete m_pEngine; m_pEngine = NULL; } printf("CCar destructor\n");}// invokerint _tmain(int argc, _TCHAR* argv[]){ // in heap CCar* pCar = new CCar; if (!pCar->init()) { CCX_SAFE_DELETE(pCar); } // in stack CCar car; if (!car.init()) { // do sth. } return 0;} |
下载样本代码请参见附件“TwoPhaseConstruction.zip”。该项目已经在Win32环境+VS2008测试过。
|
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
|
/** CCX_PROPERTY_READONLY is used to declare a protected variable. We can use get method to read the variable. @param varType : the type of variable. @param varName : variable name. @param funName : "get + funName" is the name of the get method. @warning : The get method is a public virtual function, you should override it first. The variables and methods declared after CCX_PROPERTY_READONLY are all public. If you need protected or private, please declare.*/#define CCX_PROPERTY_READONLY(varType, varName, funName)\ protected: varType varName;\ public: virtual varType get##funName(void);/** CCX_PROPERTY is used to declare a protected variable. We can use get method to read the variable, and use the set method to change the variable. @param varType : the type of variable. @param varName : variable name. @param funName : "get + funName" is the name of the get method. "set + funName" is the name of the set method. @warning : The get and set methods are public virtual functions, you should override them first. The variables and methods declared after CCX_PROPERTY are all public. If you need protected or private, please declare.*/#define CCX_PROPERTY(varType, varName, funName)\ protected: varType varName;\ public: virtual varType get##funName(void);\ public: virtual void set##funName(varType var);/** CCX_SYNTHESIZE_READONLY is used to declare a protected variable. We can use get method to read the variable. @param varType : the type of variable. @param varName : variable name. @param funName : "get + funName" is the name of the get method. @warning : The get method is a public inline function. The variables and methods declared after CCX_SYNTHESIZE_READONLY are all public. If you need protected or private, please declare.*/#define CCX_SYNTHESIZE_READONLY(varType, varName, funName)\ protected: varType varName;\ public: inline varType get##funName(void){ return varName; }/** CCX_SYNTHESIZE is used to declare a protected variable. We can use get method to read the variable, and use the set method to change the variable. @param varType : the type of variable. @param varName : variable name. @param funName : "get + funName" is the name of the get method. "set + funName" is the name of the set method. @warning : The get and set methods are public inline functions. The variables and methods declared after CCX_SYNTHESIZE are all public. If you need protected or private, please declare.*/#define CCX_SYNTHESIZE(varType, varName, funName)\ protected: varType varName;\ public: inline varType get##funName(void){ return varName; }\ public: inline void set##funName(varType var){ varName = var; } |
Objc中一些函数会返回“ID“,在转换成CPP后就会返回“bool”。在Objc中,你可以像“[[MyClass alloc] init] autorelease]”一样编写代码,无需在意初始化是否失败返回NULL。在这种情况下“[nil autorelease]”不会使程序崩溃。但是在CPP中,返回“bool”是为了防止开发人员编写“pClass = (new MyClass())->init()->foo()”。如果初始化失败返回NULL,在CPP中“null->fool()”会崩溃然后跳出程序。另一方面,如果“foo()”返回值不是“MyClass*”,例如返回“bool”,那调用者就会失去“new MyClass”的指针,然后无法从堆栈(heap)中删除指针。这就会很危险。
|
1
2
|
@interface CTest-(id) foo(); |
以上代码必须转换为
|
1
2
3
4
|
class CTest{ bool foo();} |
目的
在Cocos2dx场景中点击按钮,即可向本地平台Java弹出对话框发送信息。详见本文。
指令
你需要对项目执行几次include(包含)指令,本人已创建一个在线Repo库,根据开发环境种类分成了几个部分。请确保include(包含)了所有C++和Java的文件。在线Repo连接如下:EasyNDK。
从C++包含
|
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
|
#include "NDKHelper.h" // The button click method of Cocos2dxvoid HelloWorld::menuCloseCallback(CCObject* pSender){ // Register a selector in a global space // So that when our native environment will call the method with the string // It can respond to the selector // Note : Group name is there for ease of removing the selectors NDKHelper::AddSelector("HelloWorldSelectors", "SampleSelector", callfuncND_selector(HelloWorld::SampleSelector), this); // Making parameters for message to be passed to native language // For the ease of use, i am sending the method to be called name from C++ CCDictionary* prms = CCDictionary::create(); prms->setObject(CCString::create("SampleSelector"), "to_be_called"); // Finally call the native method in current environment SendMessageWithParams(string("SampleSelector"), prms);}// A selector that will respond to us, when native language will call itvoid HelloWorld::SampleSelector(CCNode *sender, void *data){ CCLog("Called from native environment");}// Destructor to remove all the selectors which are grouped as HelloWorldSelectorsHelloWorld::~HelloWorld(){ // Remove the associated selector group from the global space, // Because we are destroying this instance NDKHelper::RemoveSelectorsInGroup("HelloWorldSelectors");} |
从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
|
/** Called when the activity is first created. */public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); // In the main Activity, assigning that activity as a receiver for C++ messages AndroidNDKHelper.SetNDKReciever(this);}// Implement the method to be called for a message from C++// Be sure to name the method to be of the same string as you will pass from C++// Like we passed "SampleSelector" from C++, that is why created this methodpublic void SampleSelector(JSONObject prms){ Log.v("SampleSelector", "purchase something called"); Log.v("SampleSelector", "Passed params are : " + prms.toString()); String CPPFunctionToBeCalled = null; try { CPPFunctionToBeCalled = prms.getString("to_be_called"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("This is a sample popup on Android"). setTitle("Hello World!"). setNeutralButton("OK", null).show(); // Send C++ a message with paramerts // C++ will recieve this message, only if the selector list will have a method // with the string we are passing AndroidNDKHelper.SendMessageWithParameters(CPPFunctionToBeCalled, null);} |
注意 若连接其他SDK,你可以参考相关SDK的Java指南并分别实施消息传递机制从Cocos2d-x进行调用。本人通过这种方法已经实现了AppCircle、Flurry以及其他很多SDK。 拥有完整源码的样本项目可从网上下载:Sample Android Project。 祝编程愉快!
从Objective-C转战C++ Android平台开发实践(C++/Java)
原文:http://www.cnblogs.com/hackerl/p/4116038.html