2012-01-03 61 views
4

林在目標C++工作。我堅持的問題是我需要將std :: vector傳遞給客觀的c方法。這可能嗎?下面是我當前的代碼,我需要在向量定義方法中對向量進行計算(向數組成員添加偏移值),然後將其作爲C數組傳遞給方法。理想的情況下,我想設定的偏移值在第二方法中,從而分離了定義(會有這些中的幾種) 偏移將完全不同於在下面的例子中的變量。的的std ::向量的目標C方法

因此,不是通過在(b2Vec2 *)VECT我想使用矢量

- (void)createterrain1 { 

using namespace std; 
vector<b2Vec2>vecVerts; 
vector<int>::size_type i; 
vecVerts.push_back(b2Vec2(-1022.5f/100.0, -20.2f/100.0)); 
vecVerts.push_back(b2Vec2(-966.6f/100.0, -18.0f/100.0)); 
vecVerts.push_back(b2Vec2(-893.8f/100.0, -10.3f/100.0)); 
vecVerts.push_back(b2Vec2(-888.8f/100.0, 1.1f/100.0)); 
vecVerts.push_back(b2Vec2(-804.0f/100.0, 10.3f/100.0)); 
vecVerts.push_back(b2Vec2(-799.7f/100.0, 5.3f/100.0)); 
vecVerts.push_back(b2Vec2(-795.5f/100.0, 8.1f/100.0)); 
vecVerts.push_back(b2Vec2(-755.2f/ 100.0, -9.5f/100.0)); 
vecVerts.push_back(b2Vec2(-632.2f/100.0, 5.3f/100.0)); 
vecVerts.push_back(b2Vec2(-603.9f/100.0, 17.3f/100.0)); 
vecVerts.push_back(b2Vec2(-536.0f/100.0, 18.0f/100.0)); 
vecVerts.push_back(b2Vec2(-518.3f/100.0, 28.6f/100.0)); 
vecVerts.push_back(b2Vec2(-282.1f/100.0, 13.1f/100.0)); 
vecVerts.push_back(b2Vec2(-258.1f/100.0, 27.2f/100.0)); 
vecVerts.push_back(b2Vec2(-135.1f/100.0, 18.7f/100.0)); 
vecVerts.push_back(b2Vec2(9.2f/100.0, -19.4f/100.0)); 
vecVerts.push_back(b2Vec2(483.0f/100.0, -18.7f/100.0)); 
vecVerts.push_back(b2Vec2(578.4f/100.0, 11.0f/100.0)); 
vecVerts.push_back(b2Vec2(733.3f/100.0, -7.4f/100.0)); 
vecVerts.push_back(b2Vec2(827.3f/100.0, -1.1f/100.0)); 
vecVerts.push_back(b2Vec2(1006.9f/100.0, -20.2f/100.0)); 
vecVerts.push_back(b2Vec2(1023.2fdddddd/100.0, -20.2f/100.0)); 
i = vecVerts.size(); 


//I would like to pass this sets of calculations to the stitch method below rather 
than do it here 

vector<b2Vec2>::iterator pos; 

//add y offset value to our b2Vec2 
for(pos = vecVerts.begin();pos != vecVerts.end();++pos) 

{ 
    //get b2Vec2 value at index 
    b2Vec2 currVert = *pos; 

    //add y offset (this will come from the sprite image size latterly, set value for testing only 
    b2Vec2 addVert = b2Vec2(currVert.x,currVert.y + 40 /PTM_RATIO); 

    //copy offset added b2Vec2 back to vector as index 
    pos->b2Vec2::operator=(addVert); 
} 


//currently using this as kludge to pass my vector to the stitch method 
b2Vec2 * chain = &vecVerts[0]; 
[self stitchterrainvertswith:chain num:i]; 

這是我在我的向量傳遞爲C風格陣列

-(void)stitchterrainvertswith:(b2Vec2 *)verts num:(int)num { 


//create bodydef 
b2BodyDef groundBodyDef; 

//set body as static 
groundBodyDef.type = b2_staticBody; 

//set body position 
groundBodyDef.position.Set(0, 0); 

//create body using def 
groundBody = world->CreateBody(&groundBodyDef); 

//create shapes 

b2EdgeShape screenEdge; 
b2ChainShape terrain; 

terrain.CreateChain(verts, num); 
    groundBody->CreateFixture(&terrain,0); 

//keeps track of max x value for all the ground pieces that are added to the scene 
    //maxVerts.x += totalXVerts.x; 
    } 

我嘗試使用當前的方法std :: vector的一個objc包裝但是在這裏丟失了一些東西是我的例子:

VecWrap.h 
#import "Box2D.h" 
#include <vector> 

struct VecAcc; 

@interface VecWrap : NSObject 
{ 
struct VecAcc* vec; 
} 
@end 

VecWrap.MM 

#import "VecWrap.h" 

struct VecAcc { 
std::vector<b2Vec2>data; 
}; 


@implementation VecWrap 


-(id)init 
{ 
    vec = 0; 
    if (self == [super init]) { 
    vec = new VecAcc; 
} 
    return self; 
} 

-(void)dealloc 

{ 
delete vec; 
[super dealloc]; 
} 
@end 

然後creat編輯以下方法:

-(void)stitchgroundvectswith:(VecAcc*)vecs num:(int)num; 

哪個不行,這甚至有可能嗎?

回答

7

正確的自由,和巴里沃克的解決方案作品,但我不建議這樣做,因爲特定語言的預處理器伎倆像這樣的脆弱IMO。特別是,如果涉及命名空間,它們將無法正常工作,只能在指針上工作。

首先,我強烈建議開發者保持他們的ObjC和C++儘可能分開,並儘量減少ObjC++到它真正需要的幾個地方。 ObjC++是一個瘋狂的語言,GDB經常有麻煩,傷害電弧性能,編譯速度較慢,一般主要是有用的,在次入侵,而不是一個真正的語言。

我推薦這種方法來隱藏從ObjC你的C++方法標題:

@interface MyClass 

- (void)anOtherMethodCalledFromObjC; 

#ifdef __cplusplus 
- (void)stitchGroundVectsWithVector:(std::vector<b2Vec2>)vec; 
#endif 
@end 

但一般來說,我建議最你的程序是.M和.cpp文件,有幾個.mm文件將它們粘合在一起。

有關如何在舊代碼中執行此操作的詳細討論,請參閱Wrapping C++-Take 2。較新的代碼不需要ivars在標題中,因此今天應該更簡單。

+0

感謝您的幫助和建議Rob! – coasty 2012-01-03 16:45:12

1

使用Objective-C++,沒有理由不能將stichgroundvectswith:定義爲-(void)stitchgroundvectswith:(std::vector<bVect2>&)vets num:(int)num,就像您使用直接C++一樣。在此模式下,C++對象可以無縫地(具有某些注意事項)集成到Obj-C方法中。

3

你不必編寫包裝。這就是Objective-C++的目的:你可以聲明一個Obj-C方法來接受/返回一個C++對象,它將起作用。例如:

- (void)someMethod:(const std::vector<b2Vec2>&)vec { 
    /* do something with vec in C++ code */ 
} 
2

作爲@ H2CO3和@Joshua溫伯格指出,目標C++讓你定義的方法與std::vector類型的參數(或它們的參考等)。如果你將所有包含相關的.h文件的文件保留在Objective-C++中,這將工作得很好。但是,如果你需要到頭導入Objective-C的編譯文件,你需要通過指針,隱藏Objective-C代碼的類型:

#ifdef CPLUSPLUS 
typedef std::vector* vecp_t 
#else 
typedef void* vecp_t 
#endif 

@interface MyClass 
{} 

- (void)anOtherMethodCalledFromObjC; 
- (void)stitchGroundVectsWithVector:(vecp_t)vec; 
@end 

(我已經採取了Objective-C的風格化的方法名)