Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.20;
Скачать: CL | DM;

Вниз

String to PChar conversion   Найти похожие ветки 

 
Ega23 ©   (2005-02-04 17:07) [0]

Коллеги, столкнулся со следующей проблемой.
Есть 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 привожу.
Как это корректно делать надо?


 
Vlad ©   (2005-02-04 17:10) [1]


> Ega23 ©   (04.02.05 17:07)  

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


 
esu ©   (2005-02-04 17:13) [2]

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) [3]

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

С уважением,


 
Ega23 ©   (2005-02-04 17:14) [4]

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


 
esu ©   (2005-02-04 17:14) [5]

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


 
Ega23 ©   (2005-02-04 17:15) [6]

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


 
Vlad ©   (2005-02-04 17:15) [7]


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

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


 
esu ©   (2005-02-04 17:21) [8]


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

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


 
Ega23 ©   (2005-02-04 17:32) [9]

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

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


 
Ega23 ©   (2005-02-04 17:41) [10]

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


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


 
Vlad ©   (2005-02-04 17:46) [11]

StrDispose


 
Ega23 ©   (2005-02-04 17:52) [12]

StrDispose

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


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

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

Советую в купе с функцией, которая возвращает указатель на такую структуру, создать процедуру, которая будет освобождать память, выделенную для нее и ее членов (естессно, все в одной 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)

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


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

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


 
jack128 ©   (2005-02-04 21:43) [15]

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


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

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

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



Страницы: 1 вся ветка

Текущий архив: 2005.02.20;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.051 c
1-1107447640
Relaxxx
2005-02-03 19:20
2005.02.20
Один из динамически созданых компонентов нужно удалить


3-1106577778
DimonNew
2005-01-24 17:42
2005.02.20
Сохранение файлов в BLOB поле


14-1107192332
iZEN
2005-01-31 20:25
2005.02.20
Перегнать Адресную книгу между оутглюками 2002<->2003


14-1107152749
Думкин
2005-01-31 09:25
2005.02.20
С днем рождения! 31 января


1-1107531869
ShimON
2005-02-04 18:44
2005.02.20
Отследить нажатие на крестик