Open GavinRay97 opened 3 years ago
Maybe it generates them, but does it links? ( ͡° ͜ʖ ͡°)
Yep, addType is macro expanded to typedef, that's second annoyance after templates.
Though it's not technically broken, it just expands out of context.
As for generated stuff, be careful with these, it is generated for your host platform, if you build with it on another OS it might introduce subtle bugs because of ABI difference, so for now always (re)generate on target platform.
There is also subtle detail about __gshared static
globals when you link against libraries, it will introduce second symbol and result is unpredictable, so it also needs to be marked export
depending on link target.
P.S. $schema
field is for VS Code JSON intellisense, maybe it'll work if you point to schema file on github, it does works locally though
There is also subtle detail about __gshared static globals when you link against libraries, it will introduce second symbol and result is unpredictable, so it also needs to be marked export depending on link target.
Ahh I did not know this, thanks for telling me
P.S. $schema field is for VS Code JSON intellisense, maybe it'll work if you point to schema file on github, it does works locally though
I use VS Code but I also didn't know you could use an URL for the schema. I have been copying it to every project folder manually 😂 I will link to Github raw URL instead
Maybe it generates them, but does it links? ( ͡° ͜ʖ ͡°)
Ha, I should try to link the z3
one. It's a C API so I'd imagine it would -- that's maybe not the most impressive demo 😅
The REAPER one worked fantastic though, I have built stuff with it, it did a full working translation.
(Though for that one, it was actually not linked, but instead the entrypoint is called by a third-party binary, with a function used to get the fn-ptrs to the methods in the header)
// ./reaper/generated.d
module reaper.generated;
extern (C++) @cppclasssize(32) align(8) struct reaper_plugin_info_t
{
@cppsize(4) public int caller_version;
@cppsize(8) public HWND hwnd_main;
@cppsize(8) public int function(const(char)*, void*) Register;
@cppsize(8) public void* function(const(char)*) GetFunc;
}
// Struct just used for __traits reflection
// to load the function pointers into the generated definitions at runtime
__gshared struct Reaper
{
static:
bool function(const(char)*, const(char)*, const(char)*, bool) AddCustomizableMenu;
bool function() AddExtensionsMainMenu;
MediaItem* function(MediaTrack*) AddMediaItemToTrack;
// etc...
void function(const(char)*) ShowConsoleMsg;
}
// app.d
import reaper = reaper.generated;
void load_reaper_api(reaper.reaper_plugin_info_t* rec)
{
foreach (name; __traits(allMembers, reaper.Reaper))
{
// reaper.Reaper.ShowConsoleMsg = cast(typeof(reaper.Reaper.ShowConsoleMsg) rec.GetFunc("ShowConsoleMsg");
mixin(`alias tmp = reaper.Reaper.`, name);
mixin(q{
tmp = cast(typeof(tmp)) rec.GetFunc(name);
if (tmp is null) throw new Exception("Failed to load REAPER function: " ~ name);
});
}
}
extern (C) export int ReaperPluginEntry(HINSTANCE hInstance, reaper.reaper_plugin_info_t* rec)
{
load_reaper_api(rec);
reaper.Reaper.ShowConsoleMsg("Hello from Dlang!");
return 1;
}
In fact, I saw this trick recently from your .NET host repo, and I have been saving it to clean that up:
// https://github.com/Superbelko/dotnethost-d/blob/7bee104c844b2753bfcd326371a6ac2dea8e438a/source/dotnet/host.d#L154-L162
mixin template InjectFunctionPointers(T)
{
static foreach (fptr; __traits(allMembers, T))
{
static if (isFunctionPointer!(__traits(getMember, T, fptr)))
{
mixin(typeof(__traits(getMember, T, fptr)).stringof, " ", fptr, ";");
}
}
}
// Modify it to take a function for loading the function pointer, then:
InjectFunctionPointers!(reaper.Reaper)
+1 for this idea. I'd love to use this to generate bindings to Wt, but I am struggling to do so.
Open up a new issue with help request, I'll try to help sort it out. Though as I see Wt relies heavily on STL and Boost, this is serious problem for the current generator, without lots of manual tweaking of the produced code there is no way it will work.
I think this would be a really cool way to share translations of useful libs with others, and also to show examples of what
Ohmygentool
is capable of, and the quality + accuracy of code it can produce 😃I would be willing to start, I would just need to create repos for:
Also I believe Imperatorn had some degree of success translation both header types & function body code for this repo, which includes
PDCurses
in-tree:I think it would also probably be helpful to see other people's
gentool-config.json
and notes on manual changes (if any) to the source to get it to compile, or changes to generated code. This way people could pick up on helpful tricks and common approaches.Where the repo readme is something like this maybe:
Z3 C API translated to D
Generated: (gist here in lieu of actual source) https://gist.github.com/GavinRay97/66f301b5a905de6b1739688553699253
How to generate
z3/src/api
Ohmygentool
v0.3.0
gentool-config.json
configuration we need (see below)#pragma once
in every file ininput.paths
in the JSON belowgentool ./gentool-config.json