Objective C 方法中的 std::vector

发布于 2024-12-25 04:00:14 字数 3638 浏览 3 评论 0原文

我在 Objective 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;

哪个不起作用,这可能吗?

Im working in objective C++. The issue I am stuck with is that I need to pass a std::vector to an objective c method. Is this possible? Below is my current code where I am having to do my calculations on the vector in the vector definition method (adding an offset value to the members of the array) before passing to the method as a C array. Ideally I would like to set the offset values in the second method, thus splitting up the definition (there will be several of these)
The offset will be variable unlike in the example below.

So instead of passing in (b2Vec2 *)vect i want to use vectors

- (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];

This is my current method passing in my vector as a C styled array

-(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;
    }

I tried using an objc wrapper for std::vector but got kind of lost here is my example:

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

and then created the following method:

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

Which doesn't work is this even possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

稚气少女 2025-01-01 04:00:14

一切正确,巴里·沃克的解决方案有效,但我不推荐它,因为像这样的特定于语言的预处理器技巧在我看来是脆弱的。特别是,如果涉及命名空间,它们将无法正常工作,并且仅适用于指针。

首先,我强烈建议开发人员尽可能将 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 文件将它们粘合在一起。

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

All correct, and Barry Wark's solution works but I don't recommend it because language-specific pre-processor tricks like this are fragile IMO. In particular, they don't work correctly if there are namespaces involved, and only work on pointers.

First, I strongly recommend that developers keep their ObjC and C++ separate as much as possible and minimize ObjC++ to a few places where it's really needed. ObjC++ is a crazy language that gdb often has trouble with, hurts ARC performance, compiles slower, and generally is mostly a useful-at-times hack rather than a real language.

I recommend this approach to hiding your C++ methods from ObjC in headers:

@interface MyClass

- (void)anOtherMethodCalledFromObjC;

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

But generally speaking, I recommend that most of your program be .m and .cpp files, with a few .mm files to glue them together.

For extensive discussion on how to do this in older code, see Wrapping C++-Take 2. Newer code doesn't require ivars to be in the headers, so it should be even simpler to implement today.

木槿暧夏七纪年 2025-01-01 04:00:14

您不必编写包装器。这就是 Objective-C++ 的目的:你可以声明一个 Obj-C 方法来接受/返回一个 C++ 对象,并且它会起作用。例如:

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

You don't have to write wrappers. That's the purpose of Objective-C++: you can declare an Obj-C method to accept/return a C++ object and it will work. For example:

- (void)someMethod:(const std::vector<b2Vec2>&)vec {
    /* do something with vec in C++ code */
}
無心 2025-01-01 04:00:14

使用 Objective-C++,您没有理由不能将 stichgroundvectswith: 定义为 -(void)stitchgroundvectswith:(std::vector&)vets num:(int) num 就像您直接使用 C++ 一样。在此模式下,C++ 对象可以无缝(有某些注意事项)集成到 Obj-C 方法中。

With Objective-C++ there is no reason you can't just define stichgroundvectswith: as -(void)stitchgroundvectswith:(std::vector<bVect2>&)vets num:(int)num just like if you were working in straight C++. C++ objects can be seamlessly (with certain caveats) integrated into Obj-C methods in this mode.

胡大本事 2025-01-01 04:00:14

正如 @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 风格化了您的方法名称)

As @H2CO3 and @Joshua Weinberg point out, Objective-C++ lets you define a method with an argument of type std::vector (or a reference thereof, etc.). This will work fine if you're staying within Objective-C++ for all files that include the relevant .h. If, however, you need to import that header into Objective-C-compiled files, you'll need to pass the pointer, and hide the type from Objective-C code:

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

@interface MyClass
{}

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

(I've taken the liberty of Objective-C stylizing your method names)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文