digitalmars.D.learn - Dynamic load from another context
- Wolftein (24/24) Oct 30 2013 I'm trying to design a plug-in system for my game, and i would
- TheFlyingFiddle (69/74) Oct 31 2013 Yes, by using ctfe it's possible.
I'm trying to design a plug-in system for my game, and i would like to share static members from both context (Application, Shared Library). I found out that i can get the address of a __gshared at compile time, so my question is, is it possible to build an associative array at compile-time? What i'm trying to do is: /// Template to get the address of a function. template GetAddress(alias T) { enum GetAddress = &T; } template DeclareAddress(alias T, string name) { enum DeclareAddress = "__gshared " ~ T.stringof ~ " " ~ name; } Template RegisterAddress(alias T) { addToAssociativeArray!(GetAddress!T); } mixin( DeclareAddress!(uint, shared_uint) ); RegisterAddress!(shared_uint); Then i could register some shared variables like events and when the plug-in is loaded, iterate over that array and set the correct values at runtime.
Oct 30 2013
On Thursday, 31 October 2013 at 02:45:36 UTC, Wolftein wrote:so my question is, is it possible to build an associative array at compile-time?Yes, by using ctfe it's possible. like so: enum int[string] aa = createAA(); auto createAA() { int[string] aa; aa["hello"] = 1; aa["foo"] = 123; return aa; } unittest { static assert(aa["hello"] == 1); static assert(aa["foo"] == 123); }Then i could register some shared variables like events and when the plug-in is loaded, iterate over that array and set the correct values at runtime.This is not a good idea. The address values of functions/variables in a dll changes depending on where in memory the dll gets loaded. Since the addresses are determined at runtime compiletime calculations will not be correct. Also you could use the export keyword. This makes it possible to load the variables at runtime using the core.runtime module. However there seems to be problems with the export keyword see the DIP45 http://wiki.dlang.org/DIP45 I'm currently developing a reflection library for use across DLL's. In it i've done something simillar to what you want to do. I use annotations to indicate if a variable is sharable across dlls and then the code to handle the sharing is generated from those annotations via a mixin template. So bascialy i do something like this: (Simplified version) //Pluggin.d DLLShared __gshared size_t foo; DLLShared void bar(string a) { //Do something cool. } //Does not get shared over dll. void baz() { } mixin RegisterReflection; This would be expanded into something like this. __gshared void*[string] __reflectionData; export extern(C) void*[string] getReflectionTable() { return __reflectionData; } static this() { __reflectionData["foo"] = &foo; __reflectionData["bar"] = &bar; } //MainApp. alias extern(C) void function() reflection_pt; void main() { auto pluggin = loadPluggin("some_pluggin.dll"); auto data = pluggin.findFunc!(reflection_pt) ("getReflectionTable")(); auto fooPtr = cast(size_t*)(data["foo"]); //do something with the foo value. } I got a little sidetracked at the end. Hope this helped.
Oct 31 2013