Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1374476877
Жора с Бора
2013-07-22 11:07
2014.06.29
Указатели


2-1377746622
FIL-23
2013-08-29 07:23
2014.06.29
chart имя легенды на графике


15-1387103920
Cobalt
2013-12-15 14:38
2014.06.29
copy-on-write 8-bit строки


15-1386793811
Юрий
2013-12-12 00:30
2014.06.29
С днем рождения ! 12 декабря 2013 четверг


2-1377774807
delphi.coder
2013-08-29 15:13
2014.06.29
работа с объктом TFieldDataLink





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