2
0

ModuleLoader.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. //
  2. // The graphics engine GLScene
  3. //
  4. unit ModuleLoader;
  5. {******************************************************************}
  6. { }
  7. { Project JEDI }
  8. { OS independent Dynamic Loading Helpers }
  9. { }
  10. { The initial developer of the this code is }
  11. { Robert Marquardt <[email protected]) }
  12. { }
  13. { Copyright (C) 2000, 2001 Robert Marquardt. }
  14. { }
  15. { Obtained through: }
  16. { Joint Endeavour of Delphi Innovators (Project JEDI) }
  17. { }
  18. { You may retrieve the latest version of this file at the Project }
  19. { JEDI home page, located at http://delphi-jedi.org }
  20. { }
  21. { The contents of this file are used with permission, subject to }
  22. { the Mozilla Public License Version 1.1 (the "License"); you may }
  23. { not use this file except in compliance with the License. You may }
  24. { obtain a copy of the License at }
  25. { http://www.mozilla.org/NPL/NPL-1_1Final.html }
  26. { }
  27. { Software distributed under the License is distributed on an }
  28. { "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
  29. { implied. See the License for the specific language governing }
  30. { rights and limitations under the License. }
  31. { }
  32. {******************************************************************}
  33. interface
  34. {$WEAKPACKAGEUNIT ON}
  35. // each OS gets its own IFDEFed complete code block to make reading easier
  36. {$IFDEF MSWINDOWS}
  37. uses
  38. Winapi.Windows;
  39. type
  40. // Handle to a loaded DLL
  41. TModuleHandle = HINST;
  42. const
  43. // Value designating an unassigned TModuleHandle od a failed loading
  44. INVALID_MODULEHANDLE_VALUE = TModuleHandle(0);
  45. function LoadModule(var Module: TModuleHandle; FileName: PChar): Boolean; stdcall;
  46. function LoadModuleEx(var Module: TModuleHandle; FileName: PChar; Flags: Cardinal): Boolean; stdcall;
  47. procedure UnloadModule(var Module: TModuleHandle); stdcall;
  48. function GetModuleSymbol(Module: TModuleHandle; SymbolName: PChar): Pointer; stdcall;
  49. function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: PChar; var Accu: Boolean): Pointer; stdcall;
  50. function ReadModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean; stdcall;
  51. function WriteModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean; stdcall;
  52. implementation //-------------------------------------------------------------
  53. (* load the DLL file FileName
  54. the rules for FileName are those of LoadLibrary
  55. Returns: True = success, False = failure to load
  56. Assigns: the handle of the loaded DLL to Module
  57. Warning: if Module has any other value than INVALID_MODULEHANDLE_VALUE
  58. on entry the function will do nothing but returning success. *)
  59. function LoadModule(var Module: TModuleHandle; FileName: PChar): Boolean;
  60. begin
  61. if Module = INVALID_MODULEHANDLE_VALUE then
  62. Module := LoadLibrary( FileName );
  63. Result := Module <> INVALID_MODULEHANDLE_VALUE;
  64. end;
  65. // load the DLL file FileName
  66. // LoadLibraryEx is used to get better control of the loading
  67. // for the allowed values for flags see LoadLibraryEx documentation.
  68. function LoadModuleEx(var Module: TModuleHandle; FileName: PChar; Flags: Cardinal): Boolean;
  69. begin
  70. if Module = INVALID_MODULEHANDLE_VALUE then
  71. Module := LoadLibraryEx( FileName, 0, Flags);
  72. Result := Module <> INVALID_MODULEHANDLE_VALUE;
  73. end;
  74. // unload a DLL loaded with LoadModule or LoadModuleEx
  75. // The procedure will not try to unload a handle with
  76. // value INVALID_MODULEHANDLE_VALUE and assigns this value
  77. // to Module after unload.
  78. procedure UnloadModule(var Module: TModuleHandle);
  79. begin
  80. if Module <> INVALID_MODULEHANDLE_VALUE then
  81. FreeLibrary(Module);
  82. Module := INVALID_MODULEHANDLE_VALUE;
  83. end;
  84. // returns the pointer to the symbol named SymbolName
  85. // if it is exported from the DLL Module
  86. // nil is returned if the symbol is not available
  87. function GetModuleSymbol(Module: TModuleHandle; SymbolName: PChar): Pointer;
  88. begin
  89. Result := nil;
  90. if Module <> INVALID_MODULEHANDLE_VALUE then
  91. Result := GetProcAddress(Module, SymbolName );
  92. end;
  93. // returns the pointer to the symbol named SymbolName
  94. // if it is exported from the DLL Module
  95. // nil is returned if the symbol is not available.
  96. // as an extra the boolean variable Accu is updated
  97. // by anding in the success of the function.
  98. // This is very handy for rendering a global result
  99. // when accessing a long list of symbols.
  100. function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: PChar; var Accu: Boolean): Pointer;
  101. begin
  102. Result := nil;
  103. if Module <> INVALID_MODULEHANDLE_VALUE then
  104. Result := GetProcAddress(Module, SymbolName );
  105. Accu := Accu and (Result <> nil);
  106. end;
  107. // get the value of variables exported from a DLL Module
  108. // Delphi cannot access variables in a DLL directly, so
  109. // this function allows to copy the data from the DLL.
  110. // Beware! You are accessing the DLL memory image directly.
  111. // Be sure to access a variable not a function and be sure
  112. // to read the correct amount of data.
  113. function ReadModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  114. var
  115. Sym: Pointer;
  116. begin
  117. Result := True;
  118. Sym := GetModuleSymbolEx(Module, SymbolName, Result);
  119. if Result then
  120. Move(Sym^, Buffer, Size);
  121. end;
  122. // set the value of variables exported from a DLL Module
  123. // Delphi cannot access variables in a DLL directly, so
  124. // this function allows to copy the data to the DLL!
  125. // BEWARE! You are accessing the DLL memory image directly.
  126. // Be sure to access a variable not a function and be sure
  127. // to write the correct amount of data.
  128. // The changes are not persistent. They get lost when the
  129. // DLL is unloaded.
  130. function WriteModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  131. var
  132. Sym: Pointer;
  133. begin
  134. Result := True;
  135. Sym := GetModuleSymbolEx(Module, SymbolName, Result);
  136. if Result then
  137. Move(Buffer, Sym^, Size);
  138. end;
  139. {$ENDIF}
  140. {$IFDEF Unix}
  141. uses
  142. {$IFDEF UNIX}
  143. Types,
  144. Libc;
  145. {$else}
  146. dl,
  147. Types,
  148. Baseunix,
  149. Unix;
  150. {$endif}
  151. type
  152. // Handle to a loaded .so
  153. TModuleHandle = Pointer;
  154. const
  155. // Value designating an unassigned TModuleHandle od a failed loading
  156. INVALID_MODULEHANDLE_VALUE = TModuleHandle(nil);
  157. function LoadModule(var Module: TModuleHandle; FileName: PChar): Boolean;
  158. function LoadModuleEx(var Module: TModuleHandle; FileName: PChar; Flags: Cardinal): Boolean;
  159. procedure UnloadModule(var Module: TModuleHandle);
  160. function GetModuleSymbol(Module: TModuleHandle; SymbolName: PChar): Pointer;
  161. function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: PChar; var Accu: Boolean): Pointer;
  162. function ReadModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  163. function WriteModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  164. //------------------------------------------------------------
  165. implementation
  166. //------------------------------------------------------------
  167. // load the .so file FileName
  168. // the rules for FileName are those of dlopen()
  169. // Returns: True = success, False = failure to load
  170. // Assigns: the handle of the loaded .so to Module
  171. // Warning: if Module has any other value than INVALID_MODULEHANDLE_VALUE
  172. // on entry the function will do nothing but returning success.
  173. function LoadModule(var Module: TModuleHandle; FileName: PChar): Boolean;
  174. begin
  175. if Module = INVALID_MODULEHANDLE_VALUE then
  176. Module := dlopen( FileName, RTLD_NOW);
  177. Result := Module <> INVALID_MODULEHANDLE_VALUE;
  178. end;
  179. // load the .so file FileName
  180. // dlopen() with flags is used to get better control of the loading
  181. // for the allowed values for flags see "man dlopen".
  182. function LoadModuleEx(var Module: TModuleHandle; FileName: PChar; Flags: Cardinal): Boolean;
  183. begin
  184. if Module = INVALID_MODULEHANDLE_VALUE then
  185. Module := dlopen( FileName, Flags);
  186. Result := Module <> INVALID_MODULEHANDLE_VALUE;
  187. end;
  188. // unload a .so loaded with LoadModule or LoadModuleEx
  189. // The procedure will not try to unload a handle with
  190. // value INVALID_MODULEHANDLE_VALUE and assigns this value
  191. // to Module after unload.
  192. procedure UnloadModule(var Module: TModuleHandle);
  193. begin
  194. if Module <> INVALID_MODULEHANDLE_VALUE then
  195. dlclose(Module);
  196. Module := INVALID_MODULEHANDLE_VALUE;
  197. end;
  198. // returns the pointer to the symbol named SymbolName
  199. // if it is exported from the .so Module
  200. // nil is returned if the symbol is not available
  201. function GetModuleSymbol(Module: TModuleHandle; SymbolName: PChar): Pointer;
  202. begin
  203. Result := nil;
  204. if Module <> INVALID_MODULEHANDLE_VALUE then
  205. Result := dlsym(Module, SymbolName );
  206. end;
  207. // returns the pointer to the symbol named SymbolName
  208. // if it is exported from the .so Module
  209. // nil is returned if the symbol is not available.
  210. // as an extra the boolean variable Accu is updated
  211. // by anding in the success of the function.
  212. // This is very handy for rendering a global result
  213. // when accessing a long list of symbols.
  214. function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: PChar; var Accu: Boolean): Pointer;
  215. begin
  216. Result := nil;
  217. if Module <> INVALID_MODULEHANDLE_VALUE then
  218. Result := dlsym(Module, SymbolName );
  219. Accu := Accu and (Result <> nil);
  220. end;
  221. // get the value of variables exported from a .so Module
  222. // Delphi cannot access variables in a .so directly, so
  223. // this function allows to copy the data from the .so.
  224. // Beware! You are accessing the .so memory image directly.
  225. // Be sure to access a variable not a function and be sure
  226. // to read the correct amount of data.
  227. function ReadModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  228. var
  229. Sym: Pointer;
  230. begin
  231. Result := True;
  232. Sym := GetModuleSymbolEx(Module, SymbolName, Result);
  233. if Result then
  234. Move(Sym^, Buffer, Size);
  235. end;
  236. // set the value of variables exported from a .so Module
  237. // Delphi cannot access variables in a .so directly, so
  238. // this function allows to copy the data to the .so!
  239. // BEWARE! You are accessing the .so memory image directly.
  240. // Be sure to access a variable not a function and be sure
  241. // to write the correct amount of data.
  242. // The changes are not persistent. They get lost when the
  243. // .so is unloaded.
  244. function WriteModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  245. var
  246. Sym: Pointer;
  247. begin
  248. Result := True;
  249. Sym := GetModuleSymbolEx(Module, SymbolName, Result);
  250. if Result then
  251. Move(Buffer, Sym^, Size);
  252. end;
  253. {$ENDIF}
  254. end.