Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.038 c
3-1106037802
}|{yk
2005-01-18 11:43
2005.02.20
Что бы это значило?


14-1107166520
Alexander Panov
2005-01-31 13:15
2005.02.20
Блин, флудеры.


14-1107244946
Jaxtor
2005-02-01 11:02
2005.02.20
Запуск CGI приложения и обработка его результата


1-1107811993
k@rt
2005-02-08 00:33
2005.02.20
Сохранение в TMemoryStream


14-1107278045
Шишкин Илья
2005-02-01 20:14
2005.02.20
PocketPC





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский