Страниц: [1]
  Печать  
Автор Тема: const char**  (Прочитано 10105 раз)
Hed
Full Member
***
Offline Offline

Сообщений: 106



Просмотр профиля
« : Ноября 22, 2006, 02:54:55 am »

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

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

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

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

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

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

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

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


 Помогите нубу пожалуйста.
 Заранее спасибо.
Записан
Wlad
Участник
*
Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #1 : Ноября 22, 2006, 10:44:07 am »

А так не пробовали?:
PtAddListItems (wgt, (const char**)items, 1, 0);
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #2 : Ноября 22, 2006, 11:51:57 am »

Извращенцы.

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

const char *add;

PtListAddItems(combo1, &add, 1, 0);
Записан

GrayCat
Full Member
***
Offline Offline

Сообщений: 128


Gray©at


Просмотр профиля
« Ответ #3 : Ноября 22, 2006, 12:23:31 pm »

А у меня с этим 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 );  // Так вылетает!
  };
Записан

Gray©at
Wlad
Участник
*
Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #4 : Ноября 22, 2006, 12:48:41 pm »

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

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

Сообщений: 212


Просмотр профиля
« Ответ #5 : Ноября 22, 2006, 02:54:51 pm »

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

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

Сообщений: 106



Просмотр профиля
« Ответ #6 : Ноября 23, 2006, 01:20:47 am »

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


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

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #7 : Ноября 23, 2006, 11:24:22 am »

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

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

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

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

GrayCat
Full Member
***
Offline Offline

Сообщений: 128


Gray©at


Просмотр профиля
« Ответ #8 : Ноября 23, 2006, 11:53:03 am »

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() почему-то есть разница.
Записан

Gray©at
Wlad
Участник
*
Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #9 : Ноября 23, 2006, 04:34:37 pm »

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;
...но не стыдно сказать, что это не потому, что якобы "массивы и указатели в Си - одно и тоже". Если бы это было так, то первый случай работал бы... (для случая, например,  инициализации аргумента функции) :о) Лучше говорить так: "в Си есть ряд ситуаций, употребление имени массива в которых, подразумевает передачу адреса первого элемента этого массива".
Записан
Hed
Full Member
***
Offline Offline

Сообщений: 106



Просмотр профиля
« Ответ #10 : Ноября 24, 2006, 12:41:05 am »

lestat
const char *add;

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


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

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


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


я имел в виду как это будет преподноситься
функции, а потом расматриваться в нутри нее.
Записан
Hed
Full Member
***
Offline Offline

Сообщений: 106



Просмотр профиля
« Ответ #11 : Ноября 24, 2006, 03:27:07 am »

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


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

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


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

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

Сообщений: 739


Просмотр профиля WWW
« Ответ #12 : Ноября 24, 2006, 09:07:51 am »

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

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

Не читайте книжек для чайников, полных идиотов, и книжек типа "полный С++ за 2 урокачаса". Почитайте книжку для начинающих программировать на Си (без плюсов). Вам выше обьяснили, что ваша функция аргументом хочет получить адрес указателя на тип char (указатель на указатель). Вот и заведите указатель на тип char, а потом используйте операцию получения адреса (разадресацию, унарный & этого указателя при вызове функции. Именно этого от вас хотели разработчики функции.
Записан
Страниц: [1]
  Печать  
 
Перейти в: