Lazarus 2.0.10 (2020.07.11.)
Letöltés

file Windows Dll

  • makgab
  • makgab profilkép
  • Törzstag
  • Törzstag
  • Hozzászólások: 280
  • Karma: -1
  • Köszönetek: 1

makgab válaszolt a témára: Windows Dll

Köszönöm! Valóban ez volt a hiba! :)
#2081

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 432
  • Karma: 8
  • Köszönetek: 70

Gábor válaszolt a témára: Windows Dll

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.
#2080

  • makgab
  • makgab profilkép
  • Törzstag
  • Törzstag
  • Hozzászólások: 280
  • Karma: -1
  • Köszönetek: 1

makgab válaszolt a témára: Windows Dll

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.
#2079

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 432
  • Karma: 8
  • Köszönetek: 70

Gábor válaszolt a témára: Windows Dll

Igen...
#2078

  • makgab
  • makgab profilkép
  • Törzstag
  • Törzstag
  • Hozzászólások: 280
  • Karma: -1
  • Köszönetek: 1

makgab válaszolt a témára: Windows Dll

Most nem vagyok windows közelben én sem ( :) ), de a dll forrásában érted?
#2077

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 432
  • Karma: 8
  • Köszönetek: 70

Gábor válaszolt a témára: Windows Dll

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;
#2076

  • makgab
  • makgab profilkép
  • Törzstag
  • Törzstag
  • Hozzászólások: 280
  • Karma: -1
  • Köszönetek: 1

makgab létrehozta a témát: Windows Dll

Ü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?
#2075