home *** CD-ROM | disk | FTP | other *** search
- 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.
-
-