![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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)
Ты передаешь указатель на одну и ту же переменную.
А она у тебя принимает постоянно разные значения, вот и получаешь чушь в итоге.