Форум: "Начинающим";
Текущий архив: 2014.06.29;
Скачать: [xml.tar.bz2];
ВнизУказатели Найти похожие ветки
← →
Жора с Бора (2013-07-22 11:07) [0]Добрый день! Никогда не работал в Delphi, а вот тут пришлось поставить. Не могу разобраться с указателями. Есть внешняя stdcall dll. Там, к примеру, есть функция:
implementation
Function Version: PChar; stdcall;external "mydll.DLL"
Делаю так:procedure TfrmMain.cmd01Click(Sender: TObject);
var tmpString: ShortString;
p:PChar;
begin
p:=Version;
tmpString:=ShortString(p^);
txtdebug.Text:=tmpString;
end;
Возвращает 1.
Меняю объявление указателя на Pointer:procedure TfrmMain.cmd01Click(Sender: TObject);
var tmpString: ShortString;
p:Pointer;
begin
p:=Version;
tmpString:=ShortString(p^);
txtdebug.Text:=tmpString;
end;
Возвращает .25.
Что ж такое, я точно знаю, что функция должна возвращать 1.25.
Как бы мне объявить указатель, чтобы все-же мое значение пришло целиком ко мне.
И еще, как в Delphi выводить переменные в отладку, в Edit все же не очень удобно. Спасибо!
← →
RWolf © (2013-07-22 11:29) [1]
txtdebug.Text:=Version;
← →
Dennis I. Komarov © (2013-07-22 11:30) [2]tmpString:=StrPas(p);
← →
Жора с Бора (2013-07-22 11:32) [3]Благодарю, уже прочитал, что тип String это сам по себе указатель =)
← →
Жора с Бора (2013-07-22 11:33) [4]Ну, и еще если кто объяснит мне смысл того зоопарка. что я понаписал, буду премного благодарен.
← →
RWolf © (2013-07-22 11:36) [5]
> [4]
да не нужно это всё.
присвоение PChar"а строке обрабатывается корректно — копированием в неё содержимого источника до первого нулевого символа.
← →
Жора с Бора (2013-07-22 12:02) [6]А обратно как корректно обработать?
Например вызвать такую функцию, есть 2 Edit"а txtLogin и txtPass ?Function Login( AUser, APsw: PChar ): BOOL; stdcall;external "mydll.DLL"
← →
MBo © (2013-07-22 12:08) [7]передавать с использованием прямого приведения типов PChar(StringVar)
← →
RWolf © (2013-07-22 12:08) [8]
Res:=Login(PChar(MyUser), PChar(MyPsw));
← →
icWasya © (2013-07-22 14:35) [9]Ну, и еще если кто объяснит мне смысл того зоопарка. что я понаписал, буду премного благодарен.
Со строками есть несколько Compiller-Magic.procedure TfrmMain.cmd01Click(Sender: TObject);
var
tmpString: ShortString;
p:PChar;
begin
p:=Version;
tmpString:=ShortString(p^);
txtdebug.Text:=tmpString;
end;
предположим, как в твоём примере функция Version выглядит так
char * Version()
{
return "1.25";
}
по буквам
1)p:=Version;
Здесь ты получаешь из программы указатель на массив Char-ов и присваиваешь переменной типа указатель на Char.
2)tmpString:=ShortString(p^);
Вот тут происходит две вещи
первая
p^тут происходит разыменование p. То есть берётся первый элемент массива - в твоём случае символ "1". Пока всё штатно.
вторая
Ещё со времен паскаля существует преобразование Char->ShortString, описаное в руководстве по языку, то есть выражение типа Char неявно преобразуется в строку длиной в один символ и с содержимым, равным этому Char.
Поэтому tmpString = "1";
procedure TfrmMain.cmd01Click(Sender: TObject);
var
tmpString: ShortString;
p:Pointer;
begin
p:=Version;
tmpString:=ShortString(p^);
txtdebug.Text:=tmpString;
end;
1)p:=Version;
Здесь ты получаешь из программы указатель на массив Char-ов и присваиваешь переменной типа указатель. В Си - эквивалент void*;
2)tmpString:=ShortString(p^);
p^тут разыменование p уже невозможно, потому что безтиповый указатель.
Поэтому делается попытка преобразовать то, на что указывает p сразу в ShortString, безо всякой Compiller-Magic.
А ShortString устроена так - нулевой символ - это длина строки, а начиная с первого - содержимое строки.
И в результате в tmpString присваивается интересная строка - Length = 49, а содержимое = ".25"#0"мусор длиной в 45 символов".
Можешь посмотреть в отладчике.
Но при присваивании такой строки в качестве текста в Едит, строка обрубится по первому нулевому символу.
И в результате в txtdebug покажется текст ".25";
И в завершении
совсем правильноtxtdebug.Text:=StrPas(Version);
И начиная с D-2 существует неявное преобразование PChar->AnsiString, и можно прямо писатьtxtdebug.Text:=Version;
Как-то так
← →
Дмитрий (2013-08-27 18:46) [10]http://www.transl-gunsmoker.ru/2009/09/blog-post.html
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2014.06.29;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.002 c