GLS.ModuleLoader.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. //
  2. // The multimedia graphics platform GLScene https://github.com/glscene
  3. //
  4. unit GLS.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. //--------------------------------------------------------------------
  53. implementation
  54. //--------------------------------------------------------------------
  55. (* load the DLL file FileName
  56. the rules for FileName are those of LoadLibrary
  57. Returns: True = success, False = failure to load
  58. Assigns: the handle of the loaded DLL to Module
  59. Warning: if Module has any other value than INVALID_MODULEHANDLE_VALUE
  60. on entry the function will do nothing but returning success. *)
  61. function LoadModule(var Module: TModuleHandle; FileName: PChar): Boolean;
  62. begin
  63. if Module = INVALID_MODULEHANDLE_VALUE then
  64. Module := LoadLibrary( FileName );
  65. Result := Module <> INVALID_MODULEHANDLE_VALUE;
  66. end;
  67. // load the DLL file FileName
  68. // LoadLibraryEx is used to get better control of the loading
  69. // for the allowed values for flags see LoadLibraryEx documentation.
  70. function LoadModuleEx(var Module: TModuleHandle; FileName: PChar; Flags: Cardinal): Boolean;
  71. begin
  72. if Module = INVALID_MODULEHANDLE_VALUE then
  73. Module := LoadLibraryEx( FileName, 0, Flags);
  74. Result := Module <> INVALID_MODULEHANDLE_VALUE;
  75. end;
  76. // unload a DLL loaded with LoadModule or LoadModuleEx
  77. // The procedure will not try to unload a handle with
  78. // value INVALID_MODULEHANDLE_VALUE and assigns this value
  79. // to Module after unload.
  80. procedure UnloadModule(var Module: TModuleHandle);
  81. begin
  82. if Module <> INVALID_MODULEHANDLE_VALUE then
  83. FreeLibrary(Module);
  84. Module := INVALID_MODULEHANDLE_VALUE;
  85. end;
  86. // returns the pointer to the symbol named SymbolName
  87. // if it is exported from the DLL Module
  88. // nil is returned if the symbol is not available
  89. function GetModuleSymbol(Module: TModuleHandle; SymbolName: PChar): Pointer;
  90. begin
  91. Result := nil;
  92. if Module <> INVALID_MODULEHANDLE_VALUE then
  93. Result := GetProcAddress(Module, SymbolName );
  94. end;
  95. // returns the pointer to the symbol named SymbolName
  96. // if it is exported from the DLL Module
  97. // nil is returned if the symbol is not available.
  98. // as an extra the boolean variable Accu is updated
  99. // by anding in the success of the function.
  100. // This is very handy for rendering a global result
  101. // when accessing a long list of symbols.
  102. function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: PChar; var Accu: Boolean): Pointer;
  103. begin
  104. Result := nil;
  105. if Module <> INVALID_MODULEHANDLE_VALUE then
  106. Result := GetProcAddress(Module, SymbolName );
  107. Accu := Accu and (Result <> nil);
  108. end;
  109. // get the value of variables exported from a DLL Module
  110. // Delphi cannot access variables in a DLL directly, so
  111. // this function allows to copy the data from the DLL.
  112. // Beware! You are accessing the DLL memory image directly.
  113. // Be sure to access a variable not a function and be sure
  114. // to read the correct amount of data.
  115. function ReadModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  116. var
  117. Sym: Pointer;
  118. begin
  119. Result := True;
  120. Sym := GetModuleSymbolEx(Module, SymbolName, Result);
  121. if Result then
  122. Move(Sym^, Buffer, Size);
  123. end;
  124. // set the value of variables exported from a DLL Module
  125. // Delphi cannot access variables in a DLL directly, so
  126. // this function allows to copy the data to the DLL!
  127. // BEWARE! You are accessing the DLL memory image directly.
  128. // Be sure to access a variable not a function and be sure
  129. // to write the correct amount of data.
  130. // The changes are not persistent. They get lost when the
  131. // DLL is unloaded.
  132. function WriteModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  133. var
  134. Sym: Pointer;
  135. begin
  136. Result := True;
  137. Sym := GetModuleSymbolEx(Module, SymbolName, Result);
  138. if Result then
  139. Move(Buffer, Sym^, Size);
  140. end;
  141. {$ENDIF}
  142. {$IFDEF Unix}
  143. uses
  144. {$IFDEF UNIX}
  145. Types,
  146. Libc;
  147. {$else}
  148. dl,
  149. Types,
  150. Baseunix,
  151. Unix;
  152. {$endif}
  153. type
  154. // Handle to a loaded .so
  155. TModuleHandle = Pointer;
  156. const
  157. // Value designating an unassigned TModuleHandle od a failed loading
  158. INVALID_MODULEHANDLE_VALUE = TModuleHandle(nil);
  159. function LoadModule(var Module: TModuleHandle; FileName: PChar): Boolean;
  160. function LoadModuleEx(var Module: TModuleHandle; FileName: PChar; Flags: Cardinal): Boolean;
  161. procedure UnloadModule(var Module: TModuleHandle);
  162. function GetModuleSymbol(Module: TModuleHandle; SymbolName: PChar): Pointer;
  163. function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: PChar; var Accu: Boolean): Pointer;
  164. function ReadModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  165. function WriteModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  166. //------------------------------------------------------------
  167. implementation
  168. //------------------------------------------------------------
  169. // load the .so file FileName
  170. // the rules for FileName are those of dlopen()
  171. // Returns: True = success, False = failure to load
  172. // Assigns: the handle of the loaded .so to Module
  173. // Warning: if Module has any other value than INVALID_MODULEHANDLE_VALUE
  174. // on entry the function will do nothing but returning success.
  175. function LoadModule(var Module: TModuleHandle; FileName: PChar): Boolean;
  176. begin
  177. if Module = INVALID_MODULEHANDLE_VALUE then
  178. Module := dlopen( FileName, RTLD_NOW);
  179. Result := Module <> INVALID_MODULEHANDLE_VALUE;
  180. end;
  181. // load the .so file FileName
  182. // dlopen() with flags is used to get better control of the loading
  183. // for the allowed values for flags see "man dlopen".
  184. function LoadModuleEx(var Module: TModuleHandle; FileName: PChar; Flags: Cardinal): Boolean;
  185. begin
  186. if Module = INVALID_MODULEHANDLE_VALUE then
  187. Module := dlopen( FileName, Flags);
  188. Result := Module <> INVALID_MODULEHANDLE_VALUE;
  189. end;
  190. // unload a .so loaded with LoadModule or LoadModuleEx
  191. // The procedure will not try to unload a handle with
  192. // value INVALID_MODULEHANDLE_VALUE and assigns this value
  193. // to Module after unload.
  194. procedure UnloadModule(var Module: TModuleHandle);
  195. begin
  196. if Module <> INVALID_MODULEHANDLE_VALUE then
  197. dlclose(Module);
  198. Module := INVALID_MODULEHANDLE_VALUE;
  199. end;
  200. // returns the pointer to the symbol named SymbolName
  201. // if it is exported from the .so Module
  202. // nil is returned if the symbol is not available
  203. function GetModuleSymbol(Module: TModuleHandle; SymbolName: PChar): Pointer;
  204. begin
  205. Result := nil;
  206. if Module <> INVALID_MODULEHANDLE_VALUE then
  207. Result := dlsym(Module, SymbolName );
  208. end;
  209. // returns the pointer to the symbol named SymbolName
  210. // if it is exported from the .so Module
  211. // nil is returned if the symbol is not available.
  212. // as an extra the boolean variable Accu is updated
  213. // by anding in the success of the function.
  214. // This is very handy for rendering a global result
  215. // when accessing a long list of symbols.
  216. function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: PChar; var Accu: Boolean): Pointer;
  217. begin
  218. Result := nil;
  219. if Module <> INVALID_MODULEHANDLE_VALUE then
  220. Result := dlsym(Module, SymbolName );
  221. Accu := Accu and (Result <> nil);
  222. end;
  223. // get the value of variables exported from a .so Module
  224. // Delphi cannot access variables in a .so directly, so
  225. // this function allows to copy the data from the .so.
  226. // Beware! You are accessing the .so memory image directly.
  227. // Be sure to access a variable not a function and be sure
  228. // to read the correct amount of data.
  229. function ReadModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  230. var
  231. Sym: Pointer;
  232. begin
  233. Result := True;
  234. Sym := GetModuleSymbolEx(Module, SymbolName, Result);
  235. if Result then
  236. Move(Sym^, Buffer, Size);
  237. end;
  238. // set the value of variables exported from a .so Module
  239. // Delphi cannot access variables in a .so directly, so
  240. // this function allows to copy the data to the .so!
  241. // BEWARE! You are accessing the .so memory image directly.
  242. // Be sure to access a variable not a function and be sure
  243. // to write the correct amount of data.
  244. // The changes are not persistent. They get lost when the
  245. // .so is unloaded.
  246. function WriteModuleData(Module: TModuleHandle; SymbolName: PChar; var Buffer; Size: Cardinal): Boolean;
  247. var
  248. Sym: Pointer;
  249. begin
  250. Result := True;
  251. Sym := GetModuleSymbolEx(Module, SymbolName, Result);
  252. if Result then
  253. Move(Buffer, Sym^, Size);
  254. end;
  255. {$ENDIF}
  256. end.