Один указатель на два указателя
От: Аноним  
Дата: 22.12.04 06:52
Оценка:
Здравствуйте. Встала проблема передать в потоковую функцию два указателя на абсолютно несвязанные классы. Мне хочется все эти указатели завернуть в один массив и его уже передать в потоковую функцию, а то писать класс обертку мне кажется очень некрасивым решением. Как это можно сделать? Спасибо
Re: Один указатель на два указателя
От: Laurel  
Дата: 22.12.04 07:00
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте. Встала проблема передать в потоковую функцию два указателя на абсолютно несвязанные классы. Мне хочется все эти указатели завернуть в один массив и его уже передать в потоковую функцию, а то писать класс обертку мне кажется очень некрасивым решением. Как это можно сделать? Спасибо


Ну, если обязательно хочется массив, то так:

void foo(void *in_ptrs[2])
{
        void *ptr1 = in_ptrs[0];
        void *ptr2 = in_ptrs[1];        
        
}

void *ptr_array[2];

ptr_array[0] = ptr1;
ptr_array[1] = ptr2;

foo(ptr_array);
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re: Один указатель на два указателя
От: vadim77 Израиль  
Дата: 22.12.04 07:02
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте. Встала проблема передать в потоковую функцию два указателя на абсолютно несвязанные классы. Мне хочется все эти указатели завернуть в один массив и его уже передать в потоковую функцию, а то писать класс обертку мне кажется очень некрасивым решением. Как это можно сделать? Спасибо


Что тебе мешает передевать struct? Я понимаю что по сути тот же class и тем не менее наиболее стандартное решение на мой взгляд.
Re[2]: Один указатель на два указателя
От: Аноним  
Дата: 22.12.04 07:28
Оценка:
L>
L>void foo(void *in_ptrs[2])
L>{
L>        void *ptr1 = in_ptrs[0];
L>        void *ptr2 = in_ptrs[1];        
        
L>}

L>void *ptr_array[2];

L>ptr_array[0] = ptr1;
L>ptr_array[1] = ptr2;

L>foo(ptr_array);
L>


Нет так не пойдет, ведь у меня функция потоковая и ей нужно передавать параметры, созданные в куче, а не на стеке, а у Вас массив создается на стеке, следовательно, после завершения, функции создания потока, массив будет разрушен. Или я чего не понимаю((
Re[3]: Один указатель на два указателя
От: Laurel  
Дата: 22.12.04 07:35
Оценка:
Здравствуйте, <Аноним>, Вы писали:

L>>
L>>void foo(void *in_ptrs[2])
L>>{
L>>        void *ptr1 = in_ptrs[0];
L>>        void *ptr2 = in_ptrs[1];        
        
L>>}

L>>void *ptr_array[2];

L>>ptr_array[0] = ptr1;
L>>ptr_array[1] = ptr2;

L>>foo(ptr_array);
L>>


А>Нет так не пойдет, ведь у меня функция потоковая и ей нужно передавать параметры, созданные в куче, а не на стеке, а


Да, я ушами прохлопал.

Ну, тогда

void **ptr_array;
ptr_array = new (void *)[2];
ptr_array[0] = ptr1;
ptr_array[1] = ptr2;
...
delete []ptr_array;
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[4]: Один указатель на два указателя
От: Аноним  
Дата: 22.12.04 07:42
Оценка:
L>Ну, тогда

L>
L>void **ptr_array;
L>ptr_array = new (void *)[2]; // ВОТ ТУТ ОШИБКА
L>ptr_array[0] = ptr1;
L>ptr_array[1] = ptr2;
L>...
L>delete []ptr_array;
L>
Re[5]: Один указатель на два указателя
От: Laurel  
Дата: 22.12.04 07:48
Оценка:
Здравствуйте, <Аноним>, Вы писали:

L>>Ну, тогда


L>>
L>>void **ptr_array;
L>>ptr_array = new (void *)[2]; // ВОТ ТУТ ОШИБКА
L>>ptr_array[0] = ptr1;
L>>ptr_array[1] = ptr2;
L>>...
L>>delete []ptr_array;
L>>


Блин, да просто скобки надо убрать

ptr_array = new void *[2];
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[5]: Один указатель на два указателя
От: Аноним  
Дата: 22.12.04 07:49
Оценка:
Здравствуйте, Аноним, Вы писали:

L>>Ну, тогда


L>>
L>>void **ptr_array;
L>>ptr_array = new (void *)[2]; // ВОТ ТУТ ОШИБКА
L>>ptr_array[0] = ptr1;
L>>ptr_array[1] = ptr2;
L>>...
L>>delete []ptr_array;
L>>



Опять не компилится, где собака порылась. Вот код

//Вызов
void **params;
ThreadFunc(&params);


void ThreadFunc(void* params)
{
    ((SomeClass*)((*params)[0]))->SomeFunc(10);
}
Re[5]: Один указатель на два указателя
От: Laurel  
Дата: 22.12.04 07:50
Оценка:
Здравствуйте, <Аноним>, Вы писали:

Чтобы исключить возможность еще где-нибудь наглючить написал, откомпилировал, запустил, работает:

#include <stdio.h>

void foo(void **in_ptrs)
{
    printf("%p, %p", in_ptrs[0], in_ptrs[1]);
}


void main(void)
{
    void **ptr_array = new void *[2];

    ptr_array[0] = (void *) 0x1234;
    ptr_array[1] = (void *) 0x4321;

    foo(ptr_array);
}
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re: Один указатель на два указателя
От: zcbh  
Дата: 22.12.04 07:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте. Встала проблема передать в потоковую функцию два указателя на абсолютно несвязанные классы. Мне хочется все эти указатели завернуть в один массив и его уже передать в потоковую функцию, а то писать класс обертку мне кажется очень некрасивым решением. Как это можно сделать? Спасибо


Можно использовать std::pair:

void RunThread() {
    std::pair<ObjectA*, ObjectB*>  param;
    Execute(Run, (void *)&param);
}

void Run(void* param) {
    //Только не забыть param к std::pair<ObjectA*, ObjectB*> привести
    ObjectA* a = param->first;
    ObjectB* b = param->second;
}
Re[6]: Один указатель на два указателя
От: Laurel  
Дата: 22.12.04 07:52
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>void **params;

А>ThreadFunc(&params);

Не надо &.
    ThreadFunc(params);


И, соответственно:

void ThreadFunc(void** params)
{
    ((SomeClass*)(params[0]))->SomeFunc(10);
}
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[7]: Один указатель на два указателя
От: Аноним  
Дата: 22.12.04 07:56
Оценка:
Здравствуйте, Laurel, Вы писали:

L>Здравствуйте, <Аноним>, Вы писали:


А>>void **params;

А>>ThreadFunc(&params);

L>Не надо &.

L>
L>    ThreadFunc(params);
L>


L>И, соответственно:


L>
L>void ThreadFunc(void** params)
L>{
L>    ((SomeClass*)(params[0]))->SomeFunc(10);
L>}
L>


Так для потоковой функции LPVOID в качестве параметра передается, а это же void *. Или я не прав
Re[8]: Один указатель на два указателя
От: zcbh  
Дата: 22.12.04 08:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Laurel, Вы писали:


L>>Здравствуйте, <Аноним>, Вы писали:


А>>>void **params;

А>>>ThreadFunc(&params);

L>>Не надо &.

L>>
L>>    ThreadFunc(params);
L>>


L>>И, соответственно:


L>>
L>>void ThreadFunc(void** params)
L>>{
L>>    ((SomeClass*)(params[0]))->SomeFunc(10);
L>>}
L>>


А>Так для потоковой функции LPVOID в качестве параметра передается, а это же void *. Или я не прав


Правы правы. Используйте std::pair. Код будет проще и понятнее.
Re[9]: Один указатель на два указателя
От: Аноним  
Дата: 22.12.04 08:07
Оценка:
А>>Так для потоковой функции LPVOID в качестве параметра передается, а это же void *. Или я не прав

Z>Правы правы. Используйте std::pair. Код будет проще и понятнее.



STL я знаю плохо, если не сложно можно пример Спасибо
Re[8]: Один указатель на два указателя
От: Laurel  
Дата: 22.12.04 08:10
Оценка:
Здравствуйте, <Аноним>, Вы писали:

L>>
L>>void ThreadFunc(void** params)
L>>{
L>>    ((SomeClass*)(params[0]))->SomeFunc(10);
L>>}
L>>


А>Так для потоковой функции LPVOID в качестве параметра передается, а это же void *. Или я не прав


Чем дальше в лес, тем больше дров...

#include <stdio.h>

void foo(void *ptr_to_ptr_array)
{
    void **in_ptrs = (void **)(ptr_to_ptr_array);
    printf("%p, %p", in_ptrs[0], in_ptrs[1]);
}


void main(void)
{
    void **ptr_array = new void *[2];

    ptr_array[0] = (void *) 0x1234;
    ptr_array[1] = (void *) 0x4321;

    foo(ptr_array);
}


Интересно, эта ветка еще сильно увеличиться?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[9]: Один указатель на два указателя
От: Laurel  
Дата: 22.12.04 08:10
Оценка:
Здравствуйте, zcbh, Вы писали:

А>>Так для потоковой функции LPVOID в качестве параметра передается, а это же void *. Или я не прав

Z>Правы правы. Используйте std::pair. Код будет проще и понятнее.

Трус не играет в хоккей.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[9]: Один указатель на два указателя
От: Аноним  
Дата: 22.12.04 08:27
Оценка:
Здравствуйте, Laurel, Вы писали:

L>Здравствуйте, <Аноним>, Вы писали:


L>>>
L>>>void ThreadFunc(void** params)
L>>>{
L>>>    ((SomeClass*)(params[0]))->SomeFunc(10);
L>>>}
L>>>


А>>Так для потоковой функции LPVOID в качестве параметра передается, а это же void *. Или я не прав


L>Чем дальше в лес, тем больше дров...


L>
L>#include <stdio.h>

L>void foo(void *ptr_to_ptr_array)
L>{
L>    void **in_ptrs = (void **)(ptr_to_ptr_array);
L>    printf("%p, %p", in_ptrs[0], in_ptrs[1]);
L>}


L>void main(void)
L>{
L>    void **ptr_array = new void *[2];

L>    ptr_array[0] = (void *) 0x1234;
L>    ptr_array[1] = (void *) 0x4321;

L>    foo(ptr_array);
L>}
L>


L>Интересно, эта ветка еще сильно увеличиться?


Спасибо Остановлюсь на этом варианте
Re[10]: Один указатель на два указателя
От: zcbh  
Дата: 22.12.04 08:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>Так для потоковой функции LPVOID в качестве параметра передается, а это же void *. Или я не прав


Z>>Правы правы. Используйте std::pair. Код будет проще и понятнее.



А>STL я знаю плохо, если не сложно можно пример Спасибо


ОК. Пример:

Есть у нас 2 объекта, допустим
ObjectA objectA;
ObjectB objectB;

Мы хотим передать указатели на них в метод, который будет запускаться в отдельном потоке.
Этот метод принимает в качестве параметра только указатель на void.


void RunThread() {
    std::pair<ObjectA*, ObjectB*>  param(&objectA, &objectB); // Создаем объект param, который хранит как раз 2 указателя
    Execute(Run, (void *)&param); // Передаем указатель на param
}

// Это та самая ThreadFunc
void Run(void* param) {
    //Только не забыть param к указателю на std::pair<ObjectA*, ObjectB*> привести
    ObjectA* a = (std::pair<ObjectA*, ObjectB*>*)param->first;
    ObjectB* b = (std::pair<ObjectA*, ObjectB*>*)param->second;

    // Имеет указатели на исходные объекты
}


Метод first возвращает перый объект хранящийся в паре (т.е. указатель на ObjectA), second соответственно второй.


В std::pair можно засунуть пару любых объектов, например:


std::pair<int, double>   foo(14, 124.5);

foo.first - вернет 14 (тип int)
foo.second - вернет 124.5 (тип double)



Код не компилировал, но надеюсь идея ясна. И старайтесь избегать использования указателей где это возможно.

Удачи.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.