OberonCore https://forum.oberoncore.ru/ |
|
WideString, PWideChar и соответствие с КП https://forum.oberoncore.ru/viewtopic.php?f=2&t=2784 |
Страница 1 из 1 |
Автор: | Роман М. [ Суббота, 14 Август, 2010 13:29 ] |
Заголовок сообщения: | WideString, PWideChar и соответствие с КП |
Пытаюсь понять внутреннее представление двухбайтовых строк во Free Pascal для использования в Компонентном Паскале внешней библиотеки (написанной на Free Pascal). Допустим, есть такая библитека: Код: Library libtest; procedure Demo (var b: PWideChar; a: PWideChar); export; begin //a := 'Hello'; // try to set initial value b := PWideChar(WideString(a) + '?!'); end; exports Demo; begin end. Теперь пишу на КП модуль описания этой демо-библиотеки: Код: MODULE TestLibDll ["libtest"]; TYPE Pointer* = POINTER TO RECORD [untagged] END; WideString* = ARRAY [untagged] OF CHAR; PWideChar* = POINTER TO WideString; PROCEDURE Demo* (VAR b: PWideChar; a: PWideChar); END TestLibDll. И сам проверочный модуль: Код: MODULE TestDll; IMPORT SYSTEM, Lib := TestLibDll, Log := StdLog; (* int - показывать ли строку также и в числовом виде *) PROCEDURE WriteLn(IN s: ARRAY OF CHAR; int: BOOLEAN); VAR i: INTEGER; BEGIN IF int THEN FOR i := 0 TO LEN(s$) DO Log.Int(ORD(s[i])) END; Log.Ln END; Log.String("=>" + s +"<="); Log.Ln; END WriteLn; PROCEDURE StrCpy(OUT dest: Lib.PWideChar; IN src: ARRAY OF CHAR); VAR l: INTEGER; BEGIN WriteLn(" src ", FALSE); WriteLn(src, FALSE); dest := src; WriteLn(" dest ", FALSE); (*l := SYSTEM.ADR(dest); Log.Int(l); Log.Ln;*) WriteLn(dest$, TRUE); WriteLn(" end ", FALSE); END StrCpy; PROCEDURE Run*; VAR a, b: Lib.PWideChar; s: ARRAY 64 OF CHAR; BEGIN StrCpy(a, "++++1234"); WriteLn("===== Demo", FALSE); WriteLn(a$, TRUE); b := NIL; Lib.Demo(b, a); WriteLn(b$, TRUE); WriteLn("------ Demo", FALSE); END Run; END TestDll. ![]() И получаю: Код: => src <= =>++++1234<= => dest <= 43 43 43 43 49 50 51 52 0 =>++++1234<= => end <= =>===== Demo<= 43 43 43 43 49 50 51 52 0 =>++++1234<= 720 63 33 0 =>ː?!<= =>------ Demo<= Не пойму что я не учёл. Может, неправильно понял структуру PWideChar... |
Автор: | Роман М. [ Суббота, 14 Август, 2010 14:24 ] |
Заголовок сообщения: | Re: WideString, PWideChar и соответствие с КП |
Заменив PWideChar на PAnsiChar в библиотеке и модуле, получил схожий результат. Зато пример с Free Pascal работает: Код: type
ByteArr = array [0.. 255] of byte; PByteArr = ^ByteArr; const Lib = 'libtest.dll'; procedure Demo (var b: PWideChar; a: PWideChar); external Lib; procedure Demo2 (var b: PAnsiChar; a: PAnsiChar); external Lib; //procedure InsidePWideChar(s: PWideChar); procedure InsidePAnsiChar(s: PAnsiChar); var t: PByteArr; i: integer; begin t := PByteArr(s); for i := 0 to 19 do write(t^[i]:4); writeln; for i := 0 to 19 do write(chr(t^[i]):4); writeln; end; var //p, s: PWideChar; p, s: PAnsiChar; begin writeln('==='); //p := PWideChar('Hello-'); p := PAnsiChar('Hello-'); writeln(AnsiString(p)); //Demo(s, p); Demo2(s, p); //InsidePWideChar(s); InsidePAnsiChar(s); //writeln(WideString(s)); writeln(AnsiString(s)); end. |
Автор: | Евгений Темиргалеев [ Суббота, 14 Август, 2010 19:02 ] |
Заголовок сообщения: | Re: WideString, PWideChar и соответствие с КП |
У ББ стандартное соглашение о вызове - виндовый stdcall. У фрипаскаля какое-то своё. Для Add параметры передаются через eax, edx, ecx. Похоже на борландский fastcall (первые три параметра, если можно, передаются через регистры). Код: P$LIBTEST_ADD$PWIDECHAR$PWIDECHAR$PWIDECHAR: Вот как с stdcall (виндовый fpc)P$LIBTEST_ADD$PWIDECHAR$PWIDECHAR$PWIDECHAR: ; Temps allocated between ebp-68 and ebp-12 ; [lib.pas] ; [4] begin push ebp mov ebp,esp sub esp,68 mov dword ptr [ebp-68],ebx ; Var a located at ebp-4 ; Var b located at ebp-8 ; Var c located at ebp-12 mov dword ptr [ebp-4],eax mov dword ptr [ebp-8],edx mov dword ptr [ebp-12],ecx ... Код: P$LIBTEST_ADD$PWIDECHAR$PWIDECHAR$PWIDECHAR: Результат ; Temps allocated between ebp-56 and ebp+0 ; [lib.pas] ; [4] begin push ebp mov ebp,esp sub esp,56 mov dword ptr [ebp-56],ebx ; Var a located at ebp+8 ; Var b located at ebp+12 ; Var c located at ebp+16 Вложение: Сорри что картинкой, но командеры в [code] не засушень, а хотелось показать ББ-е тестирование. Роман, как я увидел, использовал самый примитивный вариант с параметрами тестовой процедуры, прошитыми как константы в исходнике. В ББ есть возможность, с минимальными усилиями, эти параметры вынести ниже текста модуля. И отрабатывать без перекомпиляции/перезагрузки модуля.
|
Автор: | Роман М. [ Суббота, 14 Август, 2010 19:45 ] |
Заголовок сообщения: | Re: WideString, PWideChar и соответствие с КП |
Спасибо за помощь! Вот где собака зарыта... http://www.freepascal.org/docs-html/pro ... -1600006.3 Цитата: 6.3 Calling mechanism
By default, the calling mechanism the compiler uses is register, that is, the compiler will try to pass as much parameters as posible by storing them in a free register. Not all registers are used, because some registers have a special meaning, but this depends on the CPU. Function results are returned in the accumulator (first register), if they fit in the register. Methods calls (from either objects or clases) have an additional invisible parameter which is self. This parameter is the leftmost parameter within a method call (it is therefore the last parameter passed to the method). |
Автор: | Alexey Veselovsky [ Суббота, 14 Август, 2010 20:01 ] |
Заголовок сообщения: | Re: WideString, PWideChar и соответствие с КП |
Код: END Add; END TestDll. ⓘ TestDll.Add "a" "b" "aa" "bb" "123" "456" Кстати, один из смайликов можно было бы сделать коммандером. Хоть пользу бы приносил. Хотя... Чем ![]() |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |