Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

String to PChar conversion [D5]


Ega23 ©   (2005-02-04 17:07:00) 

Коллеги, столкнулся со следующей проблемой.
Есть DLL, в качестве выходного параметра одной из функций возвращает указатель на след. структуру:

PPersInfo=^TPersInfo;
TPersInfo=packed record
 PersNam1      : PChar;
 PersNam2      : PChar;
 PersNam3      : PChar;
 PersSex       : PChar;
 PersPasp      : PChar;
 PersWeight    : Integer;
 OrgNam        : PChar;
 DepNam        : PChar;
 ProfNam       : PChar;
 CardNr        : Integer;
 CardCod       : Integer;
 CardTypNam    : PChar;
 CardStatNam   : PChar;
 PersImgLength : Cardinal;
 PersImgBuff   : Pointer;
 IsDefined     : Integer;
end;


Структура заполняется данными из БД:

var
PersInfo:PPersInfo;

  if aQuery.IsEmpty then
   begin
    SetEmtyPersStructure(CardCod);
    Exit;
   end;

  ss:=aQuery.FieldByName('PersNam1').AsString; // Фамилия
  PersInfo^.PersNam1:= PChar(ss);
  ss:=aQuery.FieldByName('PersNam2').AsString; // Имя
  PersInfo^.PersNam2:= PChar(ss);
  ss:=aQuery.FieldByName('PersNam3').AsString; // Отчество
  PersInfo^.PersNam3:= PChar(ss);
 
.............


И вижу я, что вместо фамилии (да и остальных полей) стоит то отчество, то тип пропуска, то адрес.

Насколько понимаю, я неправильно строку к PChar привожу.
Как это корректно делать надо?


Набережных С.   (2005-02-04 22:04:00) [1]

>jack128 ©   (04.02.05 21:43) [15]

ИМХО, в мире СИ так не принято, стандарты-то WinAPI задает. Уж лучше структуру переменной длины типа length - data. Привычней как-то, пожалуй:) Ну функцию освобождения памяти, безусловно нужна.


jack128   (2005-02-04 21:43:00) [2]

Ega23 ©   (04.02.05 17:07)
А может не парится и заменить все PChar'ы на string[255]??


Владислав   (2005-02-04 20:16:00) [3]

Мдя... прошу прощения, за оформление примера... Симбиоз паскаля и си... Давно на паскале ничего не писал :о)


Владислав   (2005-02-04 20:13:00) [4]

Ох и нахлебаетесь Вы горя с таким возвращением структуры...

Советую в купе с функцией, которая возвращает указатель на такую структуру, создать процедуру, которая будет освобождать память, выделенную для нее и ее членов (естессно, все в одной dll).

function GetMyStruct: PPersInfo; stdcall;
procedure FreeMyStruct(const Struct: PPersInfo); stdcall;

а внутри... (есть куча вариантов, это пример)

MyPers: PPersInfo;

New(MyPers);
GetMem(MyPers->PersNam1, Length(ss));
Move(Pointer(ss)^, Pointer(MyPers->PersNam1)^, Length(ss));
...

...
FreeMem(MyPers->PersNam1);
Dispose(MyPers)

Это просто и понятно, но с дополнительным выделением памяти и копированием данных. Есть более быстрый, но "хакерский" способ. Если скорость важна, спрашивайте.


Ega23   (2005-02-04 17:52:00) [5]

StrDispose

Та-а-ак... Домой, однако, пора... Ведь смотрел же на StrAlloc See also ...


Vlad   (2005-02-04 17:46:00) [6]

StrDispose


Ega23   (2005-02-04 17:41:00) [7]

Например, использовать StrAlloc. И потом не забывать эту память освобождать.


А как её освобождать? Что-то никак найти не могу...


Ega23   (2005-02-04 17:32:00) [8]

Может быть проще завести обычную структуру без кучи указателей внутри, а передавать указатель сразу на эту структуру ? Имхо проще :)

А синхронизация с С++? ДЛЛ-кой не только из Делфи пользоваться будут...


esu   (2005-02-04 17:21:00) [9]


> Ega23 ©   (04.02.05 17:15) [6]

Может быть проще завести обычную структуру без кучи указателей внутри, а передавать указатель сразу на эту структуру ? Имхо проще :)


Ega23   (2005-02-04 17:15:00) [10]

2 Игорь Шевченко ©   (04.02.05 17:13) [3]
StrAlloc, говоришь...
Щас попробую...


Vlad   (2005-02-04 17:15:00) [11]


> Ega23 ©   (04.02.05 17:14) [4]

Нет, надо выделять память под каждый PersInfo^.PersNam и копировать туда значение переменной (StrPCopy например)


Ega23   (2005-02-04 17:14:00) [12]

Т.е. это что, мне надо завести 10 РАЗНЫХ стринговых переменных, каждой присваивать значение своего поля, а потом конвертить в PChar?


esu   (2005-02-04 17:14:00) [13]

короче память забываешь выделять


esu   (2005-02-04 17:13:00) [14]

ss:=aQuery.FieldByName('PersNam1').AsString; // Фамилия
 PersInfo^.PersNam1:= PChar(ss);
ss:=aQuery.FieldByName('PersNam2').AsString; // Имя
 PersInfo^.PersNam2:= PChar(ss);

Ну если я правильно понимаю то у тебя все PersNamN будут указывать на одно и то же место в памяти (начало ss)


Игорь Шевченко   (2005-02-04 17:13:00) [15]

Память надо выделять под то, на что каждый указатель будет указывать. Например, использовать StrAlloc. И потом не забывать эту память освобождать.

С уважением,


Vlad   (2005-02-04 17:10:00) [16]


> Ega23 ©   (04.02.05 17:07)  

Ты передаешь указатель на одну и ту же переменную.
А она у тебя принимает постоянно разные значения, вот и получаешь чушь в итоге.


Наверх

Титульная страница Поиск, карта сайта Написать письмо