digitalmars.D.learn - Question about function aliases
- Gary Willoughby (16/16) Dec 11 2013 For example i have some C code like this:
- dnewbie (21/37) Dec 11 2013 It's a function pointer.
- Gary Willoughby (37/82) Dec 12 2013 So i guess i need to remove the * after the Tcl_InterpDeleteProc
- bearophile (13/17) Dec 12 2013 With recent D compilers I prefer the alias with "=" and a more
- FreeSlave (9/28) Dec 12 2013 I guess alias also should include extern(C) declaration i.e. the
- Gary Willoughby (3/7) Dec 17 2013 Unfortunately that syntax doesn't compile. The alternative does
For example i have some C code like this: typedef void (Tcl_InterpDeleteProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp)); void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc* proc, ClientData clientData); I intend on converted this to D thus: alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc* proc, ClientData clientData); Is it correct keeping the * with the Tcl_InterpDeleteProc parameter or do i remove it? Is the alias above a function pointer? To call this function can i use a function literal for the Tcl_InterpDeleteProc parameter? or do i need to pass an address of the function?
Dec 11 2013
On Wednesday, 11 December 2013 at 23:42:44 UTC, Gary Willoughby wrote:For example i have some C code like this: typedef void (Tcl_InterpDeleteProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp)); void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc* proc, ClientData clientData); I intend on converted this to D thus: alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc* proc, ClientData clientData); Is it correct keeping the * with the Tcl_InterpDeleteProc parameter or do i remove it? Is the alias above a function pointer? To call this function can i use a function literal for the Tcl_InterpDeleteProc parameter? or do i need to pass an address of the function?It's a function pointer. Test: import std.stdio; alias extern(C) void function(void*) Callback; void Call(Callback c) { c(c); } extern(C) void callback(void* v) { writefln("v: %04X", v); } void main() { Callback c = &callback; Call(c); writefln("c: %04X", c); }
Dec 11 2013
On Thursday, 12 December 2013 at 00:51:56 UTC, dnewbie wrote:On Wednesday, 11 December 2013 at 23:42:44 UTC, Gary Willoughby wrote:So i guess i need to remove the * after the Tcl_InterpDeleteProc parameter from the C declaration when porting it? Using the * my tests show an error which i guess is caused by the declaration expecting a pointer to a function pointer. Here is my test: import std.stdio; // Function pointer type. alias void function(string text, int level) Tcl_InterpDeleteProc; // A function that uses the function pointer type for a parameter. void test(Tcl_InterpDeleteProc func) // <-- no * { (*func)("Hello", 100); } // A callback that going to be used as the parameter. void callback(string text, int level) { writefln("text : %s", text); writefln("level: %d", level); } // test. void main(string[] args) { // Use address of function. test(&callback); // Function literal passed as pointer. test(function(string text, int level){ writefln("text : %s", text); writefln("level: %d", level); }); } After testing i've decided on the following code for the port. Would you agree this is correct? alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; extern (C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData);For example i have some C code like this: typedef void (Tcl_InterpDeleteProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp)); void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc* proc, ClientData clientData); I intend on converted this to D thus: alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc* proc, ClientData clientData); Is it correct keeping the * with the Tcl_InterpDeleteProc parameter or do i remove it? Is the alias above a function pointer? To call this function can i use a function literal for the Tcl_InterpDeleteProc parameter? or do i need to pass an address of the function?It's a function pointer. Test: import std.stdio; alias extern(C) void function(void*) Callback; void Call(Callback c) { c(c); } extern(C) void callback(void* v) { writefln("v: %04X", v); } void main() { Callback c = &callback; Call(c); writefln("c: %04X", c); }
Dec 12 2013
Gary Willoughby:alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; extern (C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData);With recent D compilers I prefer the alias with "=" and a more aligned colums formatting of the arguments when they don't fit well in a line: alias Tcl_InterpDeleteProc = void function(ClientData clientData, Tcl_Interp* interp); extern(C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData); Also, can't you add some "const" in those arguments? Is your C function pure? It should be nothrow. Bye, bearophile
Dec 12 2013
On Thursday, 12 December 2013 at 11:11:55 UTC, bearophile wrote:Gary Willoughby:I guess alias also should include extern(C) declaration i.e. the right way is alias Tcl_InterpDeleteProc = extern(C) void function(ClientData clientData, Tcl_Interp* interp) nothrow; So your callback on D side must have C-linkage too. Lack of extern(C) in alias probably will not cause problem on Linux, but in my experience, Windows requires it otherwise you will get seg fault.alias void function(ClientData clientData, Tcl_Interp* interp) Tcl_InterpDeleteProc; extern (C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData);With recent D compilers I prefer the alias with "=" and a more aligned colums formatting of the arguments when they don't fit well in a line: alias Tcl_InterpDeleteProc = void function(ClientData clientData, Tcl_Interp* interp); extern(C) void Tcl_CallWhenDeleted(Tcl_Interp* interp, Tcl_InterpDeleteProc proc, ClientData clientData); Also, can't you add some "const" in those arguments? Is your C function pure? It should be nothrow. Bye, bearophile
Dec 12 2013
On Thursday, 12 December 2013 at 11:39:56 UTC, FreeSlave wrote:I guess alias also should include extern(C) declaration i.e. the right way is alias Tcl_InterpDeleteProc = extern(C) void function(ClientData clientData, Tcl_Interp* interp) nothrow;Unfortunately that syntax doesn't compile. The alternative does however.
Dec 17 2013