Std :: vector in an object c-method

Im working in a C ++ object. The problem I am facing is that I need to pass std :: vector to the objective c method. Is it possible? Below is my current code, where I have to do my vector calculations in the vector definition method (adding an offset value to the members of the array) before moving to the method as an array of C. Ideally, I would like to set the offset values ​​in the second method, dividing by definition (there will be several) The offset will be different from the example below.

So, instead of going through (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 style 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 the objc wrapper for std :: vector, but lost my example here:

 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; 

What doesn't work, is it possible?

+4
source share
4 answers

Everything is correct and the Barry Wark solution works, but I do not recommend it, because processor-specific preprocessing tricks like this are fragile IMOs. In particular, they do not work correctly if namespaces exist and only work with pointers.

Firstly, I highly recommend that developers limit their ObjC and C ++ as much as possible and minimize ObjC ++ in several places where it is really necessary. ObjC ++ is a crazy language that gdb often has problems with, impairs ARC performance, compiles more slowly, and is usually mostly useful time rather than a real language.

I recommend this approach to hide your C ++ methods from ObjC in the 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 multiple .mm files to glue them together.

For a detailed discussion of how to do this in older code, see C ++ Wrapper - Take 2 . Newer code does not require ivars to be in the headers, which makes it even easier to implement today.

+7
source

You do not need to write wrappers. This is the goal of Objective-C ++: you can declare an Obj-C method to accept / return a C ++ object, and it will work. For instance:

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

As @ H2CO3 and @Joshua Weinberg point out, Objective-C ++ allows you to define a method with an argument of type std::vector (or its reference, etc.). This will work fine if you stay in Objective-C ++ for all files containing the corresponding .h. If, however, you need to import this header into Objective-C compiled files, you will need to pass a pointer and hide the type from the 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 took the liberty of Objective-C styling the names of your methods)

+2
source

With Objective-C ++, there is no reason why you cannot simply define stichgroundvectswith: as -(void)stitchgroundvectswith:(std::vector<bVect2>&)vets num:(int)num , as if you were working in direct C ++. C ++ objects can be easily (with some caveats) integrated into Obj-C methods in this mode.

+1
source

Source: https://habr.com/ru/post/1389082/


All Articles