Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2014.06.29;
Скачать: CL | DM;

Вниз

Указатели   Найти похожие ветки 

 
Жора с Бора   (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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.006 c
15-1386846268
GanibalLector
2013-12-12 15:04
2014.06.29
xakep.ru


15-1386937387
Никифиров И.В.
2013-12-13 16:23
2014.06.29
Виджеты для смарт-тв Самсунг


15-1386687468
МАКсим007
2013-12-10 18:57
2014.06.29
авторское право


2-1377623196
lancomm
2013-08-27 21:06
2014.06.29
MainMenu и PageControl


15-1386869684
alex2013
2013-12-12 21:34
2014.06.29
ищем опытного программиста...