I need to fill a dae_prim *array_prim; where dae_prim is a class I created.
I want to use C style because I will pass all those data to OpenGL.
When I'm trying to make a : mesh->array_prim[i] = mysexyprim it fails with a "subscript requires size of interface".
I think I understand the problem (Obj-C wants me to use a NSArray) but how can I bypass this?
More code
class meshes:
#public:
dae_prim *prims;
int primcount;
.
model->meshes->prims = malloc(sizeof(dae_prims*) * model->meshes->primcount);
dae_prim *prims = [[dae_prim alloc]init];
model->meshes->prims[1] = prims; //here is the problem
You need to use a double pointer for meshes->prims, as you want an array of pointers.
class meshes:
#public:
dae_prim **prims; /* a C array of objects pointers */
int primcount;
model->meshes->prims = malloc(sizeof(dae_prims*) * model->meshes->primcount);
model->meshes->prims[1] = [[dae_prim alloc]init];
Cheers.
Related
I'm working on changing some Objective-C Code over to Swift, and I cannot figure out for the life of me how to take care of unsigned char arrays and bitwise operations in this specific instance of code.
Specifically, I'm working on converting the following Objective-C code (which deals with CoreBluetooth) to Swift:
unsigned char advertisementBytes[21] = {0};
[self.proximityUUID getUUIDBytes:(unsigned char *)&advertisementBytes];
advertisementBytes[16] = (unsigned char)(self.major >> 8);
advertisementBytes[17] = (unsigned char)(self.major & 255);
I've tried the following in Swift:
var advertisementBytes: CMutablePointer<CUnsignedChar>
self.proximityUUID.getUUIDBytes(advertisementBytes)
advertisementBytes[16] = (CUnsignedChar)(self.major >> 8)
The problems I'm running into are that getUUIDBytes in Swift seems to only take a CMutablePointer<CUnsignedChar> object as an argument, rather than an array of CUnsignedChars, so I have no idea how to do the later bitwise operations on advertisementBytes, as it seems it would need to be an unsignedChar array to do so.
Additionally, CMutablePointer<CUnsignedChar[21]> throws an error saying that fixed length arrays are not supported in CMutablePointers in Swift.
Could anyone please advise on potential work-arounds or solutions? Many thanks.
Have a look at Interacting with C APIs
Mostly this
C Mutable Pointers
When a function is declared as taking a CMutablePointer
argument, it can accept any of the following:
nil, which is passed as a null pointer
A CMutablePointer value
An in-out expression whose operand is a stored lvalue of type Type,
which is passed as the address of the lvalue
An in-out Type[] value,
which is passed as a pointer to the start of the array, and
lifetime-extended for the duration of the call
If you have declared a
function like this one:
SWIFT
func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ } You
can call it in any of the following ways:
SWIFT
var x: Float = 0.0
var p: CMutablePointer<Float> = nil
var a: Float[] = [1.0, 2.0, 3.0]
takesAMutablePointer(nil)
takesAMutablePointer(p)
takesAMutablePointer(&x)
takesAMutablePointer(&a)
So you code becomes
var advertisementBytes = CUnsignedChar[]()
self.proximityUUID.getUUIDBytes(&advertisementBytes)
advertisementBytes[16] = CUnsignedChar(self.major >> 8)
I am trying to determine the type of object when detecting collision with Box2d. I want to be able to assign the user data to an object and check to see if its of the correct class type
id object = b->GerUserData():
Then
if([object isKindOfClass:[MyClassObject class]])
However i just get the error "Cannot initialize a variable of type'id' with an rvalue of type 'void*'
Can anyone help me out.
Thanks
Your problem is you are trying to assign an object of type 'id' to a void * type
The method call body->GetUserData(); returns a void pointer. Here it is as defined in the header file of b2Body.h
/// Get the user data pointer that was provided in the body definition.
void* GetUserData() const;
Now, if you are using ARC (Automatic Reference Counting), you need to perform an additional step to cast it back.
id object = (__bridge id) b->GetUserData();
If you are not using ARC, then...
id object = (id) b->GetUserData();
As for checking the type, there are many ways to do this. I personally prefer having an enum called GameObjectType. I can then assign the type in the appropriate constructor of the object. Here is an example of how I do it in my games
for (b2Body * b = world->GetBodyList(); b != NULL; b = b->GetNext()) {
Box2DSprite * sprite = (__bridge Box2DSprite*) b->GetUserData();
id obj = (__bridge id) b->GetUserData();
if (sprite.gameObjectType == kGroundTypeStatic
|| sprite.gameObjectType == kWallType
|| sprite.gameObjectType == kGroundTypeDynamic) {
// Insert Logic here
} // end if
sprite.position = ccp(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
sprite.rotation = CC_RADIANS_TO_DEGREES(b->GetAngle() * -1);
} // end for
Here is how I would go about creating the sprite (Using ARC)
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position = b2Vec2(location.x/PTM_RATIO,
location.y/PTM_RATIO);
// Setting the enum value
self.gameObjectType = kTankType;
self->body = self->world->CreateBody(&bodyDef);
self->body->SetUserData((__bridge void*) self); // Obtain sprite object later
GB2ShapeCache * shapeCache = [GB2ShapeCache sharedShapeCache];
[shapeCache addFixturesToBody:self->body forShapeName:#"Earth_Tank"];
self.anchorPoint = [shapeCache anchorPointForShape:#"Earth_Tank"];
Hope this helps
I'm guessing the error is on this line:
id object = b->GetUserData();
That might be because the return type is void pointer. Try to cast it like that:
id object = (id)b->GetUserData();
I am new to managed code and i need to pass array of pointers to different structures to windows form using C++/CLI , but it didn`t work !
My problem is in the managed array, how can i correctly access its elements .
The code sequence :
array<void*> ^ ptr;//here ptr value is undefined , type array<void*> ^
ptr = gcnew array<void*> (2);// length 0x2 , 0x0 and 0x1 values are undefined of type void
class1::struct1 structObj1;
class2::struct2 structObj2;
ptr[0] = &structObj1;// value is empty of type void!!
ptr[1] = &structObj2;//value is empty of type void!!
When i watched ptr , i found the above comments.
Notice that repeating code but using unmanaged array works probably
void* ptr[2];//here ptr value is undefined , type void*[]
class1::struct1 structObj1;
class2::struct2 structObj2;
ptr[0] = &structObj1;// value is address1 of type void*
ptr[1] = &structObj2;//value is address2 of type void*
Can anyone see where is the problem??
Do I need to use unmanaged array then convert to managed? If yes, how can I do it ??
Passing unmanaged pointers in a managed array may be valid C++/CLI, but it's definitely not the ideal way to do things. Do consider creating a custom managed class (ref class in C++/CLI) to hold the structures, instead of passing around pointers.
For this, I'm assuming that struct1 and struct2 are unmanged structs. This answer only applies if that is the case.
Your existing code works for me. Here's my version, with some debugging added in.
public struct struct1 { int foo; };
public struct struct2 { float bar; };
int main(array<System::String ^> ^args)
{
array<void*> ^ ptr;
ptr = gcnew array<void*> (2);
for(int i = 0; i < ptr->Length; i++)
Debug::WriteLine("ptr[{0}] = {1:X8}", i, reinterpret_cast<int>(ptr[i]));
struct1 structObj1;
struct2 structObj2;
ptr[0] = &structObj1;
ptr[1] = &structObj2;
for(int i = 0; i < ptr->Length; i++)
Debug::WriteLine("ptr[{0}] = {1:X8}", i, reinterpret_cast<int>(ptr[i]));
struct1* pointerToStructObj1 = reinterpret_cast<struct1*>(ptr[0]);
structObj1.foo = 4;
Debug::WriteLine("pointerToStructObj1->foo = {0}", pointerToStructObj1->foo);
}
Output:
ptr[0] = 00000000
ptr[1] = 00000000
ptr[0] = 0013F390
ptr[1] = 0013F394
pointerToStructObj1->foo = 4
Edit
To use Debug::WriteLine, add using namespace System::Diagnostics.
The debugger doesn't know how to display the contents of a void*, so it just displays blank. It does display a null pointer differently, though: null shows up as <undefined value>, non-null shows up as just blank.
My philosophy on C++/CLI is: If you're going to write managed code, write managed code. Consider replacing your vector with a managed List. If you still need unmanaged objects, I strongly urge you to consider writing a managed class with properly typed pointers, rather than a void* array.
To implement such a class, create whatever fields you need, just be sure that they're pointers, not direct. (vector<foo>* instead of vector<foo>.) Create the objects with new in the constructor, and delete them in the destructor (which is called on Dispose) & finalizer.
I have a function that returns a variable and I want to know how to return an array the issue is it isn't an NSArray it is just an average C array like this...
-(b2Fixture*) addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shape
{
BodyDef *so = [shapeObjects objectForKey:shape];
assert(so);
FixtureDef *fix = so->fixtures;
int count = -1;
b2Fixture *Fixi[4];
while(fix)
{
count++;
NSLog(#"count = %d",count);
Fixi[count]= body->CreateFixture(&fix->fixture);
if (Fixi[count]!=0) {
NSLog(#"Fixi %d is not 0",count);
}
if (body->CreateFixture(&fix->fixture)!=0) {
NSLog(#"body %d is not 0",count);
}
fix = fix->next;
}
return *Fixi;
}
If you see some variable types you don't know it's because I'm using cocos2d framework to make a game but I'm returning a variable of b2Fixture... This code compiles however only saves the value of the first block of the array "fixi[0]" not the whole array like I want to pass
anyhelp :) thankyou
You can't return a local array. You'll need to do some kind of dynamic allocation or pull a trick like having the array inside a structure.
Here is a link to an in-depth article that should help you out.
In general returning C arrays by value is a bad idea, as arrays can be very large. Objective-C arrays are by-reference types - they are dynamically allocated and a reference, which is small, is what is passed around. You can dynamically allocate C arrays as well, using one of the malloc family for allocation and free for deallocation.
You can pass C structures around by value, and this is common, as in general structures tend to be small (or smallish anyway).
Now in your case you are using a small array, it has just 4 elements. If you consider passing these 4 values around by value is reasonable and a good fit for your design then you can do so simply by embedding the C array in a C structure:
typedef struct
{
b2Fixture *elements[4];
} b2FixtureArray;
...
-(b2FixtureArray) addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shape
{
BodyDef *so = [shapeObjects objectForKey:shape];
assert(so);
FixtureDef *fix = so->fixtures;
int count = -1;
b2FixtureArray Fixi;
while(fix)
{
count++;
NSLog(#"count = %d", count);
Fixi.elements[count]= body->CreateFixture(&fix->fixture);
if (Fixi.elements[count] != 0)
{
NSLog(#"Fixi %d is not 0",count);
}
if (body->CreateFixture(&fix->fixture) != 0)
{
NSLog(#"body %d is not 0", count);
}
fix = fix->next;
}
return Fixi;
}
...
// sample call outline
b2FixtureArray result = [self addFixturesToBody...]
Whether this standard C "trick" for passing arrays by value is appropriate for your case you'll have to decide.
Note: If b2fixture is an Objective-C object make sure you understand the memory management implications of having a C array of objects references depending on the memory management model (MRC, ARC, GC) you are using.
If you need to design function or method that has to return a fixed or limited size array, one possibility is to pass a pointer to the result array to the function or method as a parameter. Then the caller can take care of allocating space, or just use a local or instance variable array. You might want the called function to sanity check that the array parameter isn't NULL before using the array.
I'm looking over some code and I came across some syntax that I don't know the meaning of. What does the '->' mean?
-(void) getTransformValues:(struct transformValues_*) tv
{
tv->pos = positionInPixels_;
tv->scale.x = scaleX_;
tv->scale.y = scaleY_;
tv->rotation = rotation_;
tv->skew.x = skewX_;
tv->skew.y = skewY_;
tv->ap = anchorPointInPixels_;
tv->visible = visible_;
}
The arrow operator ('->') is used in the same place you would use the dot operator ('.'), but with a pointer to a structure instead of an object of that structure.
typedef struct _Person {
char name[200];
unsigned int age;
} Person;
If you created an object of that structure, you would use the dot operator in order to access its members:
int main()
{
Person p1;
strcpy( p1.name, "Baltasar" );
p1.age = 36;
}
However, if you a pointer to a structure, instead of the structure itself, you could only use the arrow operator, or a little bit more complex dot operator:
int main()
{
Person p1;
Person *ptrPerson = &p1; // ptrPerson points to p1
strcpy( ptrPerson->name, "Baltasar" );
ptrPerson->age = 36;
}
As I said above, you could still use the dot operator:
int main()
{
Person p1;
Person *ptrPerson = &p1; // ptrPerson points to p1
strcpy( (*ptrPerson).name, "Baltasar" );
(*ptrPerson).age = 36;
}
Of course, all of this discussion involves a lot more topics, such as pointers, the heap, etc. Hope this helps.
The -> symbol is used to access a member of a pointer type. It is the same as dereferencing the pointer and using the dot operator, i.e.,
(*tv).pos = positionInPixels_;
It's used to access a member of an object / struct pointed to by a variable.
For example tv->pos is used to access the member variable pos from the object pointed to by tv
-> is used to mean the same thing as the dot (which means to access a member of a structure, class, or union), except that -> is used when the variable is a pointer.
"->" is used in order to access a struct pointer element. In C at least...
typedef struct test {
int one;
int two;
} t_test;
t_test *foo;
/* Allocation and all the stuff */
foo->one = ...
foo->two = ...
The arrow operator (->) takes a struct pointer (to a transformValues_ in this case), dereferences it, then accesses that member variable.
IE: these are equivelant:
(* tv).pos === tv->pos
Hmmmm did you at least consider trying to find it out for yourself before posting here?
This is what I got from searching operators....