digitalmars.D.learn - Best way to call external function from another process memory?
- Skuzzi (23/23) Nov 23 2017 Hi, I am new to D and I want to use it to create some tools that
- rikki cattermole (11/29) Nov 23 2017 alias _function = extern(C) void function(const(char)* text);
- Adam D. Ruppe (25/33) Nov 23 2017 extern(C) is for __cdecl functions. For __stdcall, it is
Hi, I am new to D and I want to use it to create some tools that call certain functions from the process of a game, using an injected DLL written in D. I have reverse engineered the addresses and arguments of the function. Typically this kind of stuff is done with C++ and almost all the available resources online focus on C++. I was not able to find anything specific to this done in D. This is what a function prototype might look like in C++: typedef void (__stdcall* _function) (const char *text); _function function; Which you would then call using the address of the function in memory: function = (_function)(ADDRESS_OF_FUNCTION); function("Some text"); I want to do this in D. I understand that D uses "extern (C)" and does away with specifying calling conventions. However, how does D know the calling convention required? What if it is a __thiscall or something else, will it always be handled properly by D, just be specifying "extern (C)"? Does anyone know of a proper and recommended way to achieve this in D? Or is this a task better suited for C++? I hope to be able to use D for this, as I am enjoying learning the language. Any help is deeply appreciated, thank you very much.
Nov 23 2017
On 23/11/2017 11:35 AM, Skuzzi wrote:Hi, I am new to D and I want to use it to create some tools that call certain functions from the process of a game, using an injected DLL written in D. I have reverse engineered the addresses and arguments of the function. Typically this kind of stuff is done with C++ and almost all the available resources online focus on C++. I was not able to find anything specific to this done in D. This is what a function prototype might look like in C++: typedef void (__stdcall* _function) (const char *text); _function function;alias _function = extern(C) void function(const(char)* text); _function myFunction;Which you would then call using the address of the function in memory: function = (_function)(ADDRESS_OF_FUNCTION); function("Some text");void* ADDRESS_OF_FUNCTION = ...; myFunction = cast(_function)ADDRESS_OF_FUNCTION; myFunction(cast(const(char)*("Some text".ptr)); Literals have a \0 at the end so this is safe.I want to do this in D. I understand that D uses "extern (C)" and does away with specifying calling conventions. However, how does D know the calling convention required? What if it is a __thiscall or something else, will it always be handled properly by D, just be specifying "extern (C)"?extern takes care of calling conventions and mangling for declarations (which you are not using in the above). See[0] point 3 regarding how this all works. [0] https://dlang.org/spec/interfaceToC.html#calling_c_functions
Nov 23 2017
On Thursday, 23 November 2017 at 11:35:18 UTC, Skuzzi wrote:typedef void (__stdcall* _function) (const char *text); I want to do this in D. I understand that D uses "extern (C)" and does away with specifying calling conventions. However, how does D know the calling convention required? What if it is a __thiscall or something else, will it always be handled properly by D, just be specifying "extern (C)"?extern(C) is for __cdecl functions. For __stdcall, it is `extern(Windows)`. D doesn't actually do away with calling conventions, it just specifies them with slightly different syntax. You do still wanna make sure you get the right one.Does anyone know of a proper and recommended way to achieve this in D?Generally speaking, if you can do it in C or C++, it isn't *that* much different to do in D: the concepts are the same, just the syntax is slightly different. So the C function pointer (*foo)(arg) stuff turns into a D function pointer: `return_type function(args)` where `function` is the literal keyword `function`. The calling convention turns into one of the correct `extern` on the outside of it: `extern(C)`, `extern(C++)`, `extern(Windows)`, `extern(Pascal)`, or extern(System) and, for completeness, extern(D). The name is based on which language uses that calling convention by default. Then casts go from (type)(statement) to `cast(type)(statement)`; the addition of the `cast` keyword. And a few other little things like array from `int foo[]` to `int* foo` - use pointers for calling C functions instead of D arrays. and C's `long` is not the same as D's `long`, use `import core.stdc.config;` and the type `c_long` instead. otherwise... pretty straightforward one-to-one translation of the concepts described in C++ on the 'net over to D syntax should get you there. You can call the same Windows API functions too.
Nov 23 2017