Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Передача указателя в составе структуры


Автор: NiJazz 24.10.2004, 00:43
Структура содержит строку
Код
struct
{
  ...
  LPTSTR   lpStr;
  ...
} MyStruct;

Когда структуру передаю по именованному каналу, строка приходит пустой, хотя остальные элементы структуры, не указатели, доходят нармально. Убирал освобождение памяти, все равно не работает.
Как передать указатель, чтобы значение сохранилось? Спасибо.

Автор: chipset 24.10.2004, 01:04
NiJazz
Покажи плз. как ты её туда засовываешь?

Автор: S.A.P. 24.10.2004, 02:25
NiJazz на сколько я понимаю ты передаешь указатель на строку по именованному каналу в другой процесс, или грубо говоря, на другой комп, так делать нельзя, потому, что один процесс не может напрямую обратиться к адресному пространству другого процесса. Если тебе надо передать строку, то можешь использовать массив:
Код
char string[100];

Автор: Mad 24.10.2004, 13:25
Цитата(Perchilla @ 24.10.2004, 02:25)
так делать нельзя, потому, что один процесс не может напрямую обратиться к адресному пространству другого процесса

Вообщето можно, но надо быть уверенным, что процессы запущенны на одном компе :) и передовать, дополнительно, ID процесса и ID потока, выделившого память для строки. Но это очень крайний случай (например если надо передать между потоками полное сочинения Ленина :) )

NiJazz
Между чем (компами, процессами, потоками) ты передаеш этот указатель ?


Автор: S.A.P. 24.10.2004, 13:37
Цитата(Mad @ 24.10.2004, 13:25)
Вообщето можно
Конечно можно, через функции API, но при условии, что все происходит на одной машине. Вот только к чему такой геморрой? Надеюсь NiJazz не собирается передавать сочинения Ленина :)

Цитата(Perchilla @ 24.10.2004, 02:25)
один процесс не может напрямую обратиться к адресному пространству другого процесса
:rtfm

Автор: Mad 24.10.2004, 13:46
Цитата(Perchilla @ 24.10.2004, 13:37)
Цитата (Perchilla @ 24.10.2004, 02:25)
один процесс не может напрямую обратиться к адресному пространству другого процесса

Да может он, надо тока сегменты заранее выяснить :)

Автор: Дрон 24.10.2004, 14:47
Чего-то вы усложняете :)
Идентификаторы процессов, адресные пространства и всё такое -- это, конечно, очень хорошо, но в данном случае -- как из пушки по воробьям...
Код
struct DataContainer // вот это твоя структура
{
   ...
   LPTSTR lpStr;
   ...
};

char* Serialize(DataContainer* dcStruct, int& length)
{
   length = sizeof(DataContainer) + strlen(dcStruct->lpStr) + 1; // вычислим объём передаваемых данных
   char *bytes = new char[length]; // создадим массив
   memmove(bytes,dcStruct,sizeof(DataContainer)); // загоним в него структуру
   memmove(bytes+sizeof(DataContainer),dcStruct->lpStr,strlen(dcStruct->lpStr)+1); // допишем к нему строку
   return bytes;
}

DataContainer Deserialize(char *bytes)
{
   DataContainer temp;
   memmove(&temp,bytes,sizeof(DataContainer)); // сохраним байты в структуре
   temp.lpStr = strdup(bytes+sizeof(DataContainer)); // подправим указатель на строку
   delete[] bytes; // массив байтов нам больше не нужен
   return temp;
}

Работоспособность не проверял, но вроде всё нормально...
Только нужно ещё не забыть после передачи данных удалить массив, полученный из Serialize :)
Добавлено @ 14:50
Тут в Deserialize я предположил, что входным параметром является массив, созданный через new[], и содержащий данные полученные через канал. А в канал, естественно, был заслан массив, возвращённый функцией Serialize :)

Автор: S.A.P. 24.10.2004, 15:11
NiJazz если размер строки не велик, ИМХО удобнее строку держать в шаровом массиве.

Автор: bel_nikita 24.10.2004, 17:29
А про конструктор копирования, случаем, не забыли?

Автор: Дрон 24.10.2004, 18:25
Цитата(bel_nikita @ 24.10.2004, 18:29)
А про конструктор копирования, случаем, не забыли?

Там не в конструкторе копирования дело :)
Это ведь не присваивание, а передача данных на другой компьютер.
Фактически моя пара функций Serialize и Deserialize и выполняет функции конструктора копирования.

Автор: bel_nikita 24.10.2004, 21:29
Дрон
не ну мало ли, может по ссылке объект пихают. И симптомы похожие.
Да еще не мешало бы выравнивание структуры добавить.

Автор: Дрон 24.10.2004, 22:17
Цитата(bel_nikita @ 24.10.2004, 22:29)
Да еще не мешало бы выравнивание структуры добавить.
Да. Лучше, когда выравнивание 1 байт, хотя sizeof() возвращает правильную длину с учётом выравнивания, т.е. мой пример должен работать.

Цитата(bel_nikita @ 24.10.2004, 22:29)
И симптомы похожие

Симптомы-то похожие :)
Но здесь прикол в том, что при передаче указателя на другой комп сама строка-то не передаётся!
А вот Perchilla предожил относительно простой и правильный выход. Забить постоянный массив внутрь структуры.

Автор: bel_nikita 24.10.2004, 22:28
Цитата
Но здесь прикол в том, что при передаче указателя на другой комп сама строка-то не передаётся!

Ай-ё! Ну так че тогда голову ломать, конечно неправильно. Надо не указатель передавать, ага, типа, как Perchilla предложил.

Автор: Adil' 25.10.2004, 09:30
Цитата(bel_nikita @ 24.10.2004, 22:28)

Надо не указатель передавать, ага, типа, как Perchilla предложил
Ага - очень здорово: если строка длиной 1 символ, 99 "бесполезных" байт туда-сюда гонять - очень экономный подход :rolleyes

Автор: Mad 25.10.2004, 13:12
Вобще пердачу строки лучше делать следующим образом (псевдокод)
Код

str_len = strlen(pStr);
send(&str_len, sizeof(str_len));
send(pStr, str_len);


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)