Текущий архив: 2010.08.27;
Скачать: CL | DM;
ВнизВозвращение строки 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;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.066 c