C ++, используя (void *) для приведения к int для сравнения? - PullRequest
1 голос
/ 06 февраля 2012

Я (пытаюсь) написать какой-то (работающий) C ++ в проекте ObjC :-) Библиотека C ++ (Box2D) предоставляет мне класс b2Fixture, который имеет свойство «пользовательские данные», позволяющее кодировщикам хранить то, что имеет отношение к делу. им.

В моем случае, он просто должен хранить целое число. Из моей основной программы в ObjC одно приведение целого числа к void *:

headFixture->SetUserData( (void*) 10 );

В служебном методе на стороне C ++ программы я хотел бы сравнить пользовательские данные с заданным целым числом (т. Е. Они являются константами, 10 = сплошная земля, 11 = платформа и т. Д.).

Первое сравнение использует (void *), который отказывается компилироваться. Нашел на SO другой подход, как показано во втором сравнении, использующем * ((intptr_t *) ...). Это компилируется, но отправляет EXC_BAD_ACCESS:

bool AbstractContactListener::contactContainsType(JRContact contact, int type){

    if (( type == ( (void *) contact.fixtureA->GetUserData() )) ||
        ( type == *( (intptr_t *) contact.fixtureB->GetUserData() ))
        ) {
        return true;
    }

    return false;
}

У меня заканчиваются идеи для решения этой проблемы. Пожалуйста помоги :-) Спасибо! J.

EDIT / Решение:

bool AbstractContactListener::contactContainsType(JRContact contact, int type){

    if (( type == (intptr_t) contact.fixtureA->GetUserData() ) ||
        ( type == (intptr_t) contact.fixtureB->GetUserData() )
        ) {
        return true;
    };

    return false;
}

Этот работал для меня!

Ответы [ 3 ]

5 голосов
/ 06 февраля 2012

Я не совсем понимаю, что вы пытаетесь сделать, но вам, вероятно, следует привести данные обратно к тому типу, который вам нужен:

if (( type == reinterpret_cast<int>(contact.fixtureA->GetUserData() )) ||
    ( type == reinterpret_cast<int>(contact.fixtureB->GetUserData() ))
    ) {
2 голосов
/ 06 февраля 2012

Насколько я вижу, вам просто нужно отбросить его обратно; вам нужно использовать целочисленный тип, который гарантированно будет того же размера, что и указатель для приведения, иначе компилятор может выдать ошибку;

#include <stdint.h>

if(type == (intptr_t)(contact.fixtureA->GetUserData())) {

Существует одно предупреждение, хотя, насколько мне известно, приведение int к void * и back не гарантируется стандартом C для возврата того же значения. Более безопасным вариантом может быть использование указателей в том виде, в котором они будут использоваться;

int *value = malloc(sizeof(int));
*value = 10;
headFixture->SetUserData( value );

и

if(type == *(int*)(contact.fixtureA->GetUserData())) {

, который не должен соблазнять компилятор нарушать ваш код.

1 голос
/ 06 февраля 2012

Вы хотите использовать reinterpret_cast<int>. Если вы получаете ошибку, значит, вы делаете не совсем то, что говорите. (Вероятно, вы пытаетесь разыменовать void * как int *.)

int stored_type = reinterpret_cast<int>(contact.fixtureA->GetUserData());
...