1 module selfscript.dload;
2 
3 version (Windows) {
4     import core.sys.windows.windows;
5     import selfscript.windll;
6     import core.runtime;
7     import core.memory;
8 }
9 version (Posix) {
10     import core.sys.posix.dlfcn;
11 }
12 
13 import std.stdio;
14 import std.process;
15 import f = std.file;
16 import std.string;
17 
18 
19 // http://wiki.dlang.org/Win32_DLLs_in_D
20 // https://dlang.org/dll-linux.html
21 
22 
23 /// Holds a Script object
24 class ScriptObjectDShared {
25 
26     enum UserFunctionName = "dllFunc";
27 
28     /// Loads a compiled script object into memory. 
29     this(string name) 
30     {
31         version (Windows) {
32             string realName = name~".dll";
33         } else {
34             string realName = name~".so";
35         }
36 
37         if(!load(realName)) {
38             writeln("Cannot load compiled script '" ~ realName ~ "'!");
39         }
40     }
41 
42     /// Executes a compiled script object after loading
43     void execute()
44     {
45         if(_loaded && !(func is null)) {
46             (*func)();
47         }
48     }
49 
50     /// unloads Script Object
51     bool unload()
52     {
53         if (_loaded) {
54             version (Windows) {
55                 _loaded = !Runtime.unloadLibrary(dllHandle);
56             }
57             version (Posix) {
58                 dlclose(dllHandle);
59                 _loaded = false;
60             }
61         }
62 
63         return !_loaded;
64     }
65 
66 protected:
67 
68     /// loads the dll. name must be the path to the .dll/.so
69     bool load(string name) 
70     {
71         version(Windows) {
72             dllHandle = cast(HMODULE) Runtime.loadLibrary(name);
73             if (dllHandle is null) {
74                 return false;
75             }
76             _loaded = true;
77             dllUserFunction = GetProcAddress(dllHandle, UserFunctionName);
78             if (dllUserFunction is null) {
79                 return false;
80             }
81             func = cast(UserFunctionType) dllUserFunction;
82             return true;
83         }
84         version (Posix) {
85             dllHandle = dlopen(toStringz(name),RTLD_LAZY);
86             if (dllHandle is null) {
87                 return false;
88             }
89             _loaded = true;
90             dllUserFunction = cast(UserFunctionType) dlsym(dllHandle,toStringz(UserFunctionName));
91             auto error = dlerror();
92             if (error) {
93                 return false;
94             }
95             func = cast(UserFunctionType) dllUserFunction;
96             return true;
97         }
98 
99         assert(0);
100     }
101 
102 private: 
103     extern (C) {
104         /// type of the user function in the dll
105         alias UserFunctionType = void function();
106         /// container for the converted user function
107         UserFunctionType func;
108     }
109     version (Windows) {
110         /// handle of the dll
111         HMODULE dllHandle;
112         /// pointer to the dll function
113         FARPROC dllUserFunction;
114     } else {
115         /// handle of the dll
116         void*   dllHandle;
117         /// pointer to the dll function
118         void*   dllUserFunction;
119     }
120 
121     /// if the dll is loaded (its not relevant if the symbol was found!)
122     bool _loaded = false;
123 }
124 
125