 |
Меню |
|
|
|
|
 |
Главная |
|
| Посл.ответ |
Сообщение |
|
Дата: 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.
| | |