Lazarus 2.0.12 (2021.02.21.)
Letöltés

  • Oldal:
  • 1

TÉMA:

Windows Dll 2016 aug. 12 08:50 #2081

  • makgab
  • makgab profilkép Témaindító
  • Törzsgárda tag
  • Törzsgárda tag
  • Hozzászólások: 280
  • Köszönetek: 1
Köszönöm! Valóban ez volt a hiba! :)

Windows Dll 2016 aug. 10 14:48 #2080

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 463
  • Köszönetek: 76
Az összeadás hibás értéke egyértelműen verem (stack) probléma. A függvénytárak hívásakor az stdcall, cdecl vagy más módosító megadásakor a paraméterek másképpen lesznek kezelve (sorrendjük a veremben is eltérhet), ezért ezt egyértelműsíteni kell a függvénytárban is, hogy ne legyen zavar. Valahogy így:
library mylib;
 
{$mode objfpc}{$H+}
 
uses
  Classes, Windows, Dialogs;
 
function MyAdd( x: integer; y: integer ): integer; stdcall; export;
begin
  Result:=x+y;
end;
 
procedure MyMsg(); stdcall; export;
begin
  MessageBox( 0, PChar('MyMsg procedure run from DLL!'),PChar(''), MB_OK );
end;
 
exports MyAdd,
        MyMsg;
 
begin
end.

Az alkalmazásodat így már megfelelő értéket ír ki a MyAdd ereményeként:
procedure TForm1.Button1Click(Sender: TObject);
type
  TMyFun=function (a:Integer; b: integer):integer; stdcall;
  TMyMsg=procedure ; stdcall;
var
  MyLib: TLibHandle = dynlibs.NilHandle;
  MyFun: TMyFun;
  MyMsg: TMyMsg;
  FuncResult: integer;
begin
  FuncResult:=0;
  MyLib := SafeLoadLibrary('mylib.dll');
  if MyLib = dynlibs.NilHandle then begin
    Exit;
  end;
  MyFun:= TMyFun(GetProcedureAddress(MyLib, 'MyAdd'));
  MyMsg:= TMyMsg(GetProcedureAddress(MyLib, 'MyMsg'));
  FuncResult:= MyFun (5, 2);
  MyMsg;
//  if MyLib <>  DynLibs.NilHandle then
//    if FreeLibrary(MyLib) then
//      MyLib:= DynLibs.NilHandle;
  ShowMessage( 'Result from Dll: ' + IntToStr( FuncResult ) );
end;
A függvénytár "felszabadítását" megjegyzésbe tettem, mert nálam (Wine) kiakad miatta a program (ezen még töprengek). A függvénytár mindenképpen felszabadításra kerül ha a programod leáll.
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- FPC 3.3.1 -- Lazarus 2.1.0 -- GNU/Linux 5.4.0 x86_64

Windows Dll 2016 aug. 10 08:02 #2079

  • makgab
  • makgab profilkép Témaindító
  • Törzsgárda tag
  • Törzsgárda tag
  • Hozzászólások: 280
  • Köszönetek: 1
Nem jó, ugyanaz a hiba ezzel is:
function MyAdd( x: integer; y: integer ): integer; export;
begin
  Result:=x+y;
end;
 
procedure MyMsg(); export;
begin
  MessageBox( 0, PChar('MyMsg procedure run from DLL!'),PChar(''), MB_OK );
end;

Az export meg van/volt adva egyébként:
// ******************
// exports
// ******************
exports MyAdd,
        MyMsg;

Érdekes, hogy a MyMsg() működik, felugrik a MessageBox!
Csak a MyAdd() problémás.

Windows Dll 2016 aug. 09 22:21 #2078

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 463
  • Köszönetek: 76
Igen...
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- FPC 3.3.1 -- Lazarus 2.1.0 -- GNU/Linux 5.4.0 x86_64

Windows Dll 2016 aug. 09 18:33 #2077

  • makgab
  • makgab profilkép Témaindító
  • Törzsgárda tag
  • Törzsgárda tag
  • Hozzászólások: 280
  • Köszönetek: 1
Most nem vagyok windows közelben én sem ( :) ), de a dll forrásában érted?

Windows Dll 2016 aug. 09 18:20 #2076

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 463
  • Köszönetek: 76
Nincs előttem windows, de emlékeim szerint (persze tévedhetek :) ) az eljárások fejléce után ott kell álljon az 'export' módosító:
function MyAdd( x: integer; y: integer ): integer; export;
procedure MyMsg(); export;
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- FPC 3.3.1 -- Lazarus 2.1.0 -- GNU/Linux 5.4.0 x86_64

Windows Dll 2016 aug. 09 12:29 #2075

  • makgab
  • makgab profilkép Témaindító
  • Törzsgárda tag
  • Törzsgárda tag
  • Hozzászólások: 280
  • Köszönetek: 1
Üdv!
Tesztelem a Windows Dll hívást Lazarus-ban (1.6 x32):
wiki.freepascal.org/Lazarus/FPC_Libraries#Windows

Adott egy Dll:
library mydll;
 
{$mode objfpc}{$H+}
 
uses
  Classes, Windows,Dialogs
  { you can add units after this };
 
 
// ********************
// definitions
// ********************
function MyAdd( x: integer; y: integer ): integer;
begin
  Result:=x+y;
end;
 
procedure MyMsg();
begin
  MessageBox( 0, PChar('MyMsg procedure run from DLL!'),PChar(''), MB_OK );
end;
 
 
// ******************
// exports
// ******************
exports MyAdd,
        MyMsg;
 
begin
end.

A teszt alkalmazásban megpróbálom meghívni:
procedure TForm1.Button2Click(Sender: TObject);
type
  TMyFun=function (a:Integer; b: integer):integer; StdCall;
var
  MyLib: TLibHandle= dynlibs.NilHandle;
  MyFun: TMyFun;
  FuncResult: integer;
begin
  // MyLib := LoadLibrary('mydll' + SharedSuffix);
  MyLib := SafeLoadLibrary('mydll.dll');
  //if MyLib = dynlibs.NilHandle then
  if MyLib = 0 then
     Exit;  //DLL was not loaded successfully
  MyFun:= TMyFun(GetProcedureAddress(MyLib, 'MyAdd'));
  FuncResult:= MyFun (5, 2);  //Executes the function
  if MyLib <>  DynLibs.NilHandle then
     if FreeLibrary(MyLib) then
            MyLib:= DynLibs.NilHandle;  //Unload the lib, if already loaded
  ShowMessage( 'Result from Dll: ' + IntToStr( FuncResult ) );
end; 
A MyAdd() egy sima összeadás. Debuggolva a FuncResult nem jó eredményt kap vissza ( FuncResult:=MyFun (5, 2) <--- ennek 7-nek kellene lennie ) és a ShowMessage() függvénynél SIGSEGV-t ad.

Hol rontom el?

  • Oldal:
  • 1