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

Вниз

Возвращение строки PChar, Delphi 2009   Найти похожие ветки 

 
Darvin   (2010-03-15 11:07) [0]

Здравствуйте!
Мне нужно написать функцию на Delphi 2009, чтобы она возвращала результат в формате PChar. Вот ее реализация:

function GetName(TestID: Integer; out Name: PChar): HResult;
var
 S : String;
begin
   S := uGetData.GetName(TestID);
   if S = "" then
     Result := NOT_FOUND
   else begin
     GetMem ( Name, (Length(S) + 1) * SizeOf(Char) );
     Name := PChar(S);
     Result := SUCCESS;
   end;
end;


Перед выходом в отладчике проверяю состояние Name. Оно содержит корректные данные, скажем "Абрамов Иван Сергеевич".

Потом вызываю ее следующим образом:

var
 Name : PChar;
begin
 ...
 GetName(TestID, Name);


И вот здесь получается Name = "Абрамов <иероглифы>".
В чем я не прав?
Особенность: Эта функция из COM - интерфейса, вызывается из другого приложения


 
Игорь Шевченко ©   (2010-03-15 11:28) [1]

в D2009 PChar - это PWideChar. Ты этого хочешь ?


 
Darvin   (2010-03-15 11:34) [2]

да. Но, если я указываю PWideChar, ничего не меняется


 
Darvin   (2010-03-15 11:56) [3]

Интересно! Поменял PChar на PAnsiChar, все заработало:

function GetName(TestID: Integer; out Name: PAnsiChar): HResult;
var
S : AnsiString;
begin
  S := uGetData.GetName(TestID);
  if S = "" then
    Result := NOT_FOUND
  else begin
    GetMem ( Name, (Length(S) + 1) * SizeOf(Char) );
    Name := PAnsiChar(S);
    Result := SUCCESS;
  end;
end;


Вызов:

var
Name : PAnsiChar;
begin
...
GetName(TestID, Name);

Вопрос. А если хочу с PWideChar?


 
Anatoly Podgoretsky ©   (2010-03-15 11:59) [4]

> Darvin  (15.03.2010 11:07:00)  [0]

Слишком много ошибок.
Главная S это строка с ограниченым сроком существования и GetMem неприменимо.


 
Darvin   (2010-03-15 12:02) [5]


> Главная S это строка с ограниченым сроком существования
> и GetMem неприменимо.

Да, GetMem на результативность не влияет, я ее убрал вообще, все работает, по крайней мере видимых сбоев нет.


> Слишком много ошибок.

А не сложно ли Вам указать их все?


 
DVM ©   (2010-03-15 12:04) [6]


> Darvin   (15.03.10 11:56) [3]

Очень плохо, когда функция сама выделяет память под строку. Так делают крайне редко и в исключительных случаях.

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

Так делается в WinAPI.


 
Darvin   (2010-03-15 14:10) [7]

Экспериментируя пришел к следующему. Написал такой пример:

var
 S : String;
 Name : PChar;
begin
 S := "Привет!!!";
 GetMem ( Name, 102 );
 Name := PChar(S);
 FreeMem ( Name );


При освобождении памяти возникает ошибка Invalid Pointer Operation. Значит, я неправильно присваиваю значение для Name. А как правильно?


 
Anatoly Podgoretsky ©   (2010-03-15 14:15) [8]

> Darvin  (15.03.2010 14:10:07)  [7]

Убил память присвоением


 
DVM ©   (2010-03-15 14:27) [9]


> Darvin   (15.03.10 14:10) [7]


> Name := PChar(S);

вот этой строкой ты указатель Name переставил на другое место в памяти. Для копирования строки можно использовать например Move()


 
Darvin   (2010-03-15 14:28) [10]


> Убил память присвоением

я ЭТО понял. Я написал
> Значит, я неправильно присваиваю значение для Name

И задал вопрос:
> А как правильно?

Ответа нет...


 
DVM ©   (2010-03-15 14:29) [11]


> Ответа нет...

ответ есть, см ниже


 
Darvin   (2010-03-15 14:32) [12]

Накопал следующее:
 S := "Привет!!!";
 Name := StrNew(PChar(S));
 StrDispose(Name);

Этот код работает



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

Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.056 c
15-1269293403
Юрий
2010-03-23 00:30
2010.08.27
С днем рождения ! 23 марта 2010 вторник


15-1274268745
Alx2
2010-05-19 15:32
2010.08.27
Онлайн-интервью с председателем комиссии по борьбе с лженаукой


2-1265658323
Константин
2010-02-08 22:45
2010.08.27
Назначение процедур для динамически создаваемых контролов


2-1271881604
Б
2010-04-22 00:26
2010.08.27
Как вызвать процедуру по указателю на неё?


3-1238738221
Cabyrc
2009-04-03 09:57
2010.08.27
ConnectionString для FoxPro





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский