6

我在目标 C++ 中工作。我遇到的问题是我需要将 std::vector 传递给目标 c 方法。这可能吗?下面是我当前的代码,其中我必须在向量定义方法中对向量进行计算(向数组的成员添加偏移值),然后才能将其作为 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

然后创建了以下方法:

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

哪个行不通,这甚至可能吗?

4

4 回答 4

7

一切正确,Barry Wark 的解决方案有效,但我不推荐它,因为像这样的特定于语言的预处理器技巧是脆弱的 IMO。特别是,如果涉及命名空间,它们就不能正常工作,并且只能在指针上工作。

首先,我强烈建议开发人员尽可能将他们的 ObjC 和 C++ 分开,并将 ObjC++ 最小化到一些真正需要的地方。ObjC++ 是一种疯狂的语言,gdb 经常遇到麻烦,损害 ARC 性能,编译速度较慢,而且通常主要是一种有时有用的 hack,而不是真正的语言。

我推荐这种方法在标头中隐藏 ObjC 中的 C++ 方法:

@interface MyClass

- (void)anOtherMethodCalledFromObjC;

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

但一般来说,我建议您的大部分程序是 .m 和 .cpp 文件,并用一些 .mm 文件将它们粘合在一起。

有关如何在旧代码中执行此操作的广泛讨论,请参阅Wrapping C++-Take 2。较新的代码不需要 ivars 在标头中,因此今天实现起来应该更简单。

于 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++,没有理由不能定义stichgroundvectswith:-(void)stitchgroundvectswith:(std::vector<bVect2>&)vets num:(int)num就像在直接使用 C++ 工作一样。在这种模式下,C++ 对象可以无缝地(有一些注意事项)集成到 Obj-C 方法中。

于 2012-01-03T14:16:24.540 回答