QNX RTP Logo QNX Realtime Platform: Русский Портал QNX
Thursday, 20 Nov 2008 11:01
Меню

Проект OpenNET - все о Unix
Главная

 · Начало · Статистика · Поиск ·

  QNX.ORG.RU —› Языки и алгоритмы —› const char**

Посл.ответ Сообщение


Дата: 21 Ноя,  23:54 · Поправил: Hedrin_

Всем доброго время суток.

Столкнулся вот с ТАКОЙ проблемой...

На сколько я понял это особенность с++. Пытался найти объяснение в книгах, но толи плох искал, толи не пишут об этом...
В общем суть такова:

// ну, это знакомо...
extern PtAddListItems (PtWidget_t, const char**, int, unsigned int);

// ... здесь что-то происходит

char **items; // пробовал разные варианты...

// ... здесь опять что-то происходит

PtAddListItems (wgt, items, 1, 0); // а здесь
// компилятор меня посылает, ссылаясь на второй аргумент
// и неспособность его конвертировать.


Помогите нубу пожалуйста.
Заранее спасибо.


Дата: 22 Ноя,  07:44

А так не пробовали?:
PtAddListItems (wgt, (const char**)items, 1, 0);


Дата: 22 Ноя,  08:51

Извращенцы.

Во-первых функция называется PtListAddItems, во вторых:

const char *add;

PtListAddItems(combo1, &add, 1, 0);


Дата: 22 Ноя,  09:23 · Поправил: GrayCat

А у меня с этим PtListAddItems() прям-таки любофф: при попытке подсунуть ему строку как "автоматическую переменную" в функции - вылет по GPF. Приходится заводить просто указатель, делать ему calloc(), и в таком виде скармливать PtListAddItems().


int Func1()
{
char Str1[32];
char *Str2;

Str2 = calloc(1, 32);
strcpy(Str2, "Allocated string" ) ;
PtListAddItems(PtListWidget, &Str2, 1, 0 ); // Так работает
free(Str2);
// -----------------
strcpy( Str1, "Automatic string" ) ;
PtListAddItems(PtListWidget, &Str1, 1, 0 ); // Так вылетает!
};


Дата: 22 Ноя,  09:48

lestat
Извращенцы.

Да ладно, чё там... :о)
Человек нписал, что "и так пробовал, и - так...". А может ещё вот так не пробовал?...


Дата: 22 Ноя,  11:54

GrayCat
PtListAddItems(PtListWidget, &Str1, 1, 0 ); // Так вылетает!

И правильно делает. Потому что &Str1 - это указатель на начало массива Str1 (в данном конкретном случае - абсолютно то же, что и просто Str1). А нужен указатель на объект типа "указатель", в котором лежит адрес Str1. Чувствуете разницу?


Дата: 22 Ноя,  22:20 · Поправил: Hedrin_

Wlad
А так не пробовали?:
PtAddListItems (wgt, (const char**)items, 1, 0);


Вроде запись

fn (const <тип> аргумент_функции);

горантирует, что данный аргумент будет константным в нутри самой функции...но не иначе. И потом, я объявлял переменную константно...ни шиша.


lestat
Во-первых функция называется PtListAddItems

Но ведь главное - вы меня поняли

lestat
во вторых:

const char *add;

PtListAddItems(combo1, &add, 1, 0);


Попробую...
Могу ошибаться, но вроде это теперь выглядит вот так:

char const **add;

Еще хотелось бы узнать...
Ведь ошибка возникла когда все это дело я стал использывать в С++. В Си было все прекрастно...
Вот если кто объяснит - почему С++ не терпит такого ?

И еще...
Покапался в головнике PtList.h , там явно указанно, что функция Си-шная:

#ifdef __cplusplus
extern "C" {
#endif

int PtListAddItems(PtWidget_t *widget, const char **items, int item_count, unsigned int position);

#ifdef __cplusplus
};
#endif


...вот и подумал, - может и с этим както связана данная проблема?


Дата: 23 Ноя,  08:24

Hedrin_
Могу ошибаться, но вроде это теперь выглядит вот так: char const **add;

Одна звезда! А передача по ссылке.
Hedrin_
Вот если кто объяснит - почему С++ не терпит такого ?

В C++ жесткая типизация как следствие возможности создания перегруженных функций и методов класса для обработки любого типа.
Hedrin_
Покапался в головнике PtList.h , там явно указанно, что функция Си-шная:

С++ не значит ООП. Это идеология и немного другой язык.


Дата: 23 Ноя,  08:53

A_O
GrayCat
PtListAddItems(PtListWidget, &Str1, 1, 0 ); // Так вылетает!

И правильно делает. Потому что &Str1 - это указатель на начало массива Str1
Неправильно делает! Str1 - это переменная, указатель на начало строки. &Str1 - это уже указатель на переменную Str1, т.е. фактически массив [из одного элемента] указателей на строки. Что и требуется для PtListAddItems().

Ваше утверждение, что
A_O
абсолютно то же, что и просто Str1
- неверно. "Одно и то же" было бы Str1==&Str1[0].

В приведенном коде Str1 и Str2 - оба являются ссылками на строку, только Str1 - на уже выделенную в стеке при вызове функции, а Str2 - на выделенную в хипе перед использованием. В большинстве случаев это работает одинаково, но вот для PtListAddItems() почему-то есть разница.


Дата: 23 Ноя,  13:34 · Поправил: Wlad

GrayCatВ большинстве случаев это работает одинаково, но вот для PtListAddItems() почему-то есть разница.

Так нельзя:
char Str1[128];
char** Str = &Str1;
Потому, что слева char** , а справа - char(*)[128];
И вот так - тоже:
char Str1[128];
char* Str = &Str1;
слева char* , а справа char(*)[128];

А вот это - "естественно"-классический случай. Даже как-то стыдно упоминать :о)...
char Str1[128];
char* Str = Str1;
...но не стыдно сказать, что это не потому, что якобы "массивы и указатели в Си - одно и тоже". Если бы это было так, то первый случай работал бы... (для случая, например, инициализации аргумента функции) :о) Лучше говорить так: "в Си есть ряд ситуаций, употребление имени массива в которых, подразумевает передачу адреса первого элемента этого массива".


Дата: 23 Ноя,  21:41 · Поправил: Hedrin_

lestat
const char *add;

PtListAddItems(combo1, &add, 1, 0);


Спасибо, помогло. Больной будет жить.
Но в чем идея так и не понял. Пойду почитаю
умную книжку "С++ для чайников".

Hedrin
Могу ошибаться, но вроде это теперь выглядит вот так:
char const **add;


lestat
Одна звезда! А передача по ссылке.


я имел в виду как это будет преподноситься
функции, а потом расматриваться в нутри нее.


Дата: 24 Ноя,  00:27

lestat
С++ не значит ООП. Это идеология и немного другой язык.


Это как раз понятно...

Hedrin_
...вот и подумал, - может и с этим както связана данная проблема?


Попробую перефразировать...

Если функция обрамлена extern C{}, то значит ли это,
что ее аргументы на входе/выходе срр будет расматривать
как то иначе, чем другие?
Или все упирается только в жесткую типизацию срр?


Дата: 24 Ноя,  06:07

Hedrin_
Если функция обрамлена extern C{}, то значит ли это,
что ее аргументы на входе/выходе срр будет расматривать
как то иначе, чем другие?

Вам сюда:
http://www.open-std.org/jtc1/sc22/wg21/
Читайте параграф 7.5 Linkage specifications. Это говорит компилятору о том, что функция написана на языке С, потому как полное описание переменных в С++ включает тип, имя и тип линковки (т.е. могут быть две функции одного типа с одинаковым названием но с разным линкаджем - и они будут разными сущностями). Но, в общем, это не самое важное для вас сейчас. Главнее следующее
Hedrin_
Спасибо, помогло. Больной будет жить.
Но в чем идея так и не понял. Пойду почитаю
умную книжку "С++ для чайников".

Не читайте книжек для чайников, полных идиотов, и книжек типа "полный С++ за 2 урокачаса". Почитайте книжку для начинающих программировать на Си (без плюсов). Вам выше обьяснили, что ваша функция аргументом хочет получить адрес указателя на тип char (указатель на указатель). Вот и заведите указатель на тип char, а потом используйте операцию получения адреса (разадресацию, унарный &[img]http://qnx.org.ru/components/minibb/img/smilies/wink.gif[/img] этого указателя при вызове функции. Именно этого от вас хотели разработчики функции.

You must login to post.

©   2000-2003 Команда проекта QNX.ORG.RU // QNX.ORG.RU Team
Авторы проекта: Дмитрий Алексеев [dmi] и Дмитрий Васильев. Техническое сопровождение проекта: Игорь Сорокин [isorokin]. Информационное сопровождение: Дмитрий Алексеев [dmi]
QNX - зарегистрированная торговая марка QNX Software Systems, Ltd., Canada. Остальные упоминаемые на сайте торговые марки и логотипы являются исключительно собственностью их уважаемых владельцев. Ничьи права не затронуты. Материалы сайта не могут быть скопированы и где-либо использованы в той или иной форме без письменного разрешения разработчиков сайта.
Powered by Mambo Open Source