Dll support: testers needed

Benjamin Thaut code at benjamin-thaut.de
Tue Jan 9 18:32:24 UTC 2018


Am 09.01.2018 um 16:03 schrieb Andre Pany:
> 
> I am building a bridge between Delphi and D. At the moment the 
> executable is written in D and the Dll (Firemonkey UI) is written in 
> Delphi. But I think I want to enable also the other way around. The D 
> coding which is then located in the Dll should be able to call Delphi 
> methods located in the executable. The whole idea idea is that all logic 
> is written in D and you only use the Framework (ui) and libraries Delphi 
> provides.
> 
> I think this might be a valid use case for a Dll calling functionality 
> located in the exe.
> 
> Kind regards
> Andre

First let me say that what you are describing is a very uncommon and 
ill-advised use case. As such there is not going to be any nice to use 
workflow to acieve what you are trying to do. Still this doesn't mean 
that it won't be possible.

Why ill-advised? What you're describing is a cyclic dependency between 
your main executable and your dll written in delphi. If you google for 
"cyclic dependency dll" you will usually get the advice to break your 
cylic dependency by splitting your code into more dlls. My personal 
experience shows the same. Cyclic dependencies in dlls are usually not 
worth the additional effort and hassle. Also you want to export things 
from your executable, which is also very uncommon. What you should be 
doing is having 2 dlls and one executable. You have one common library 
written in D that is build into a dll. Then you have your delphi library 
which uses the common.dll. Finally you have your main executable written 
in D which uses both the common.dll and your delphi.dll. This should 
make it possibly to break the cycle and get you an easy setup.


If you absolutley must do it the way you describe it, its still 
possible. You will have to compile all modules that export something 
from your executable with the "-c -shared" parameters. E.g.
dmd -m64 -c -shared moduleThatExports1.d moduleThatExports2.d -ofexports.obj

Now you link the resulting exports.obj file into your executable by 
calling dmd again

dmd -m64 restOfModules.d exports.obj delphi.lib -ofmain.exe

Finally you have to get the handle to your main executable by calling

HMODULE handle;
GetModuleHandleExA(0, null, &handle);

in your delphi dll and then fetching the function pointer for each and 
every function you want to call from delphi via:

GetProcAddress(handle, "mangeledFunctionSymbol")

Now finally you can call these functions pointers from delphi and they 
will call into the D code within your executable.


Instead of all that hassle you could instead just have a function in 
your delphi dll:

void recieveFunctionPointer(const(char)* name, void* ptr);

which you call for every function that you want to make available from D 
to delphi. Your delphi code then stores away these pointers depending on 
the name. That way you don't need to export anything from your 
executable and can build it normally. Instead of having a function call 
per function you could obviosuly also use a struct that is defined the 
same way in D and delphi and contains all relevant functions pointers.

-- 
Kind Regards
Benjamin Thaut


More information about the Digitalmars-d mailing list