home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 November
/
Chip_2002-11_cd1.bin
/
zkuste
/
delphi
/
kompon
/
d456
/
CAJSCRPT.ZIP
/
ifps3
/
ifpidll2runtime.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2002-07-06
|
4KB
|
160 lines
unit ifpidll2runtime;
{$I ifps3_def.inc}
interface
uses
ifpicall, ifps3, ifps3utl, ifps3common;
{Register the dll runtime library}
procedure RegisterDLLRuntime(Caller: TIFPSExec);
{Process a dll import (no need to call this function)}
function ProcessDllImport(Caller: TIFPSExec; P: PIFProcRec): Boolean;
implementation
uses
{$IFDEF LINUX}
LibC;
{$ELSE}
Windows;
{$ENDIF}
{
p^.Ext1 contains the pointer to the Proc function
p^.ExportDecl:
'dll:'+DllName+#0+FunctionName+#0+chr(Cc)+VarParams
}
type
PLoadedDll = ^TLoadedDll;
TLoadedDll = record
dllnamehash: Longint;
dllname: string;
{$IFDEF LINUX}
dllhandle: Pointer;
{$ELSE}
dllhandle: THandle;
{$ENDIF}
end;
procedure DllFree(Sender: TIFPSExec; P: PLoadedDll);
begin
{$IFDEF LINUX}
dlclose(p^.dllhandle);
{$ELSE}
FreeLibrary(p^.dllhandle);
{$ENDIF}
Dispose(p);
end;
function DllProc(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
var
i: Integer;
MyList: TIfList;
n: PIFVariant;
CurrStack: Cardinal;
cc: TCallingConvention;
s: string;
begin
s := p^.ExportDecl;
delete(S, 1, pos(#0, s));
delete(S, 1, pos(#0, s));
if length(S) < 2 then
begin
Result := False;
exit;
end;
cc := TCallingConvention(s[1]);
delete(s, 1, 1);
CurrStack := Stack.Count - Cardinal(length(s));
if s[1] = #0 then inc(CurrStack);
MyList := tIfList.Create;
for i := 2 to length(s) do
begin
MyList.Add(nil);
end;
for i := length(s) downto 2 do
begin
n :=Stack.GetItem(CurrStack);
if s[i] <> #0 then
begin
n^.RefCount := n^.RefCount or IFPSAddrStackStart;
end;
MyList.SetItem(i - 2, n);
inc(CurrStack);
end;
try
if s[1] <> #0 then
begin
n := Stack.GetItem(CurrStack);
end else n := nil;
InnerfuseCall(Caller, nil, p^.Ext1, cc, MyList, n, nil);
result := true;
except
result := false;
end;
MyList.Free;
end;
function ProcessDllImport(Caller: TIFPSExec; P: PIFProcRec): Boolean;
var
s, s2: string;
h, i: Longint;
ph: PLoadedDll;
{$IFDEF LINUX}
dllhandle: Pointer;
{$ELSE}
dllhandle: THandle;
{$ENDIF}
begin
s := p^.ExportDecl;
Delete(s, 1, 4);
s2 := copy(s, 1, pos(#0, s)-1);
delete(s, 1, length(s2)+1);
h := makehash(s2);
i := 2147483647; // maxint
dllhandle := 0;
repeat
ph := Caller.FindProcResource2(@dllFree, i);
if i = -1 then
begin
{$IFDEF LINUX}
dllhandle := dlopen(PChar(s2), RTLD_LAZY);
{$ELSE}
dllhandle := LoadLibrary(Pchar(s2));
{$ENDIF}
if dllhandle = {$IFDEF LINUX}nil{$ELSE}0{$ENDIF}then
begin
Result := False;
exit;
end;
new(ph);
ph^.dllnamehash := h;
ph^.dllname := s2;
ph^.dllhandle := dllhandle;
Caller.AddResource(@DllFree, ph);
end;
if (ph^.dllnamehash = h) and (ph^.dllname = s2) then
begin
dllhandle := ph^.dllhandle;
end;
dec(i);
until dllhandle <> {$IFDEF LINUX}nil{$ELSE}0{$ENDIF};
{$IFDEF LINUX}
p^.Ext1 := dlsym(dllhandle, pchar(copy(s, 1, pos(#0, s)-1)));
{$ELSE}
p^.Ext1 := GetProcAddress(dllhandle, pchar(copy(s, 1, pos(#0, s)-1)));
{$ENDIF}
p^.ProcPtr := DllProc;
Result := p^.Ext1 <> nil;
end;
procedure RegisterDLLRuntime(Caller: TIFPSExec);
begin
Caller.AddSpecialProcImport('dll', @ProcessDllImport, nil);
end;
end.