6

私は客観的なC ++で作業しています。私が立ち往生している問題は、目的の c メソッドに std::vector を渡す必要があることです。これは可能ですか?以下は、C配列としてメソッドに渡す前に、ベクトル定義メソッドでベクトルに対して計算を行う(配列のメンバーにオフセット値を追加する)必要がある現在のコードです。理想的には、2 番目の方法でオフセット値を設定して、定義を分割したいと考えています (これらはいくつかあります)。以下の例とは異なり、オフセットは可変になります。

したがって、 (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

次に、次のメソッドを作成しました。

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

これは可能ですか?

4

4 に答える 4

7

すべて正しく、Barry Wark のソリューションは機能しますが、このような言語固有のプリプロセッサのトリックは脆弱な IMO であるため、お勧めしません。特に、名前空間が関係している場合は正しく機能せず、ポインターでのみ機能します。

まず、開発者は ObjC と C++ を可能な限り分離し、ObjC++ を本当に必要な場所に最小限に抑えることを強くお勧めします。ObjC++ は、gdb が頻繁に問題を起こし、ARC のパフォーマンスを低下させ、コンパイルが遅くなるクレイジーな言語であり、一般に、実際の言語というよりも、ほとんどの場合、時々役立つハックです。

ヘッダーで ObjC から C++ メソッドを非表示にするには、次の方法をお勧めします。

@interface MyClass

- (void)anOtherMethodCalledFromObjC;

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

しかし、一般的に言えば、プログラムのほとんどを .m ファイルと .cpp ファイルにし、それらを結合するためにいくつかの .mm ファイルにすることをお勧めします。

古いコードでこれを行う方法について詳しくは、C++-Take 2 のラップを参照してください。新しいコードでは ivar をヘッダーに含める必要がないため、今日の実装はさらに簡単になるはずです。

于 2012-01-03T14:50:46.083 に答える
3

ラッパーを書く必要はありません。それが Objective-C++ の目的です。Obj-C メソッドを宣言して、C++ オブジェクトを受け入れて返すことができ、それが機能します。例えば:

- (void)someMethod:(const std::vector<b2Vec2>&)vec {
    /* do something with vec in C++ code */
}
于 2012-01-03T14:19:23.277 に答える
2

@H2CO3 と @Joshua Weinberg が指摘しているように、Objective-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 で自由にメソッド名のスタイルを設定しました)

于 2012-01-03T14:35:24.557 に答える
1

Objective-C++ では、ストレート C++ で作業している場合と同じようstichgroundvectswith:に定義できない理由はありません。-(void)stitchgroundvectswith:(std::vector<bVect2>&)vets num:(int)numこのモードでは、C++ オブジェクトを Obj-C メソッドにシームレスに統合できます (ただし、いくつかの注意事項があります)。

于 2012-01-03T14:16:24.540 に答える