Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
December 26, 2016 How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Say I have a module "a" that wants to call a function "void fun()" in another module "b". The name "b" is not known until runtime, i.e. it's read from the console. (Really the name is obtained by iterating foreach (m; ModuleInfo)). How do I get fun()'s address (or the null pointer if it doesn't exist)? Thanks, Andrei |
December 26, 2016 Re: How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 2016-12-26 19:45, Andrei Alexandrescu wrote: > Say I have a module "a" that wants to call a function "void fun()" in > another module "b". The name "b" is not known until runtime, i.e. it's > read from the console. (Really the name is obtained by iterating foreach > (m; ModuleInfo)). > > How do I get fun()'s address (or the null pointer if it doesn't exist)? Perhaps use "dlopen" on the executable and then use "dlsym" and pass in the mangled name. -- /Jacob Carlborg |
December 26, 2016 Re: How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 12/26/2016 03:01 PM, Jacob Carlborg wrote:
> On 2016-12-26 19:45, Andrei Alexandrescu wrote:
>> Say I have a module "a" that wants to call a function "void fun()" in
>> another module "b". The name "b" is not known until runtime, i.e. it's
>> read from the console. (Really the name is obtained by iterating foreach
>> (m; ModuleInfo)).
>>
>> How do I get fun()'s address (or the null pointer if it doesn't exist)?
>
> Perhaps use "dlopen" on the executable and then use "dlsym" and pass in
> the mangled name.
Yah, I'm trying this:
void main()
{
void *hndl = dlopen(null, 1);
hndl !is null || assert(0);
auto n = "runAllTests".ptr;//m.name ~ "" '\0';
auto p = cast(void function()) dlsym(hndl, n);
if (!p) assert(0);
p();
}
extern(C) void* dlopen(const(char)*, int);
extern(C) void* dlsym(void*, const(char)*);
export extern(C) void runAllTests() {}
dlopen passes, dlsym fails.
Andrei
|
December 26, 2016 Re: How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Monday, 26 December 2016 at 20:19:52 UTC, Andrei Alexandrescu wrote: > Yah, I'm trying this: Your program works for me verbatim on GNU/Linux on x86_64. A more portable approach would be to instrument the modules at compile-time (e.g. by iterating the modules' members and constructing a static array), and using it at run-time. > void main() > { > void *hndl = dlopen(null, 1); > hndl !is null || assert(0); > auto n = "runAllTests".ptr;//m.name ~ "" '\0'; Perhaps try a leading underscore for the mangled function name. Not sure how things are different on OS X. > auto p = cast(void function()) dlsym(hndl, n); This will use the wrong calling convention. You need to cast to an extern(C) function pointer. |
December 26, 2016 Re: How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On 12/26/2016 04:39 PM, Vladimir Panteleev wrote: > On Monday, 26 December 2016 at 20:19:52 UTC, Andrei Alexandrescu wrote: >> Yah, I'm trying this: > > Your program works for me verbatim on GNU/Linux on x86_64. Thanks for the info. Interesting. I'm on Linux Mint building with dmd flag free. I just updated all of dmd, druntime, and phobos to the latest and greatest. > A more portable approach would be to instrument the modules at > compile-time (e.g. by iterating the modules' members and constructing a > static array), and using it at run-time. You still need to fetch the static array address. Essentially what I'm looking for is, starting from ModuleInfo, get to the address of something tangible that is planted intentionally (so I know its name). What is a good way to achieve that? >> void main() >> { >> void *hndl = dlopen(null, 1); >> hndl !is null || assert(0); >> auto n = "runAllTests".ptr;//m.name ~ "" '\0'; > > Perhaps try a leading underscore for the mangled function name. Not sure > how things are different on OS X. Yah, it's all Mint and according to objdump the name is runAllTests. >> auto p = cast(void function()) dlsym(hndl, n); > > This will use the wrong calling convention. You need to cast to an > extern(C) function pointer. Thanks for saving me some head scratching later :o). Andrei |
December 26, 2016 Re: How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Monday, 26 December 2016 at 22:32:55 UTC, Andrei Alexandrescu wrote:
> You still need to fetch the static array address. Essentially what I'm looking for is, starting from ModuleInfo, get to the address of something tangible that is planted intentionally (so I know its name). What is a good way to achieve that?
Have you already considered Object.factory?
|
December 26, 2016 Re: How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On 12/26/2016 05:35 PM, Vladimir Panteleev wrote:
> On Monday, 26 December 2016 at 22:32:55 UTC, Andrei Alexandrescu wrote:
>> You still need to fetch the static array address. Essentially what I'm
>> looking for is, starting from ModuleInfo, get to the address of
>> something tangible that is planted intentionally (so I know its name).
>> What is a good way to achieve that?
>
> Have you already considered Object.factory?
It's what I'm trying to get rid of :o). -- Andrei
|
December 27, 2016 Re: How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 12/26/2016 07:45 PM, Andrei Alexandrescu wrote: > Say I have a module "a" that wants to call a function "void fun()" in > another module "b". The name "b" is not known until runtime, i.e. it's > read from the console. (Really the name is obtained by iterating foreach > (m; ModuleInfo)). > > How do I get fun()'s address (or the null pointer if it doesn't exist)? https://github.com/dlang/druntime/pull/617 Waiting to rectify the horrible Windows DLL implementation might not have been the best choice for that. Also Windows DLL is even stuck on fixing export, haven't heard from Benjamin Thaut since DConf. -Martin |
December 27, 2016 Re: How do I find and call a function in a module I only know during runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On 2016-12-26 22:39, Vladimir Panteleev wrote: > Your program works for me verbatim on GNU/Linux on x86_64. Works for me as well on macOS, no changes required. -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation