Re: Question about function aliases
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.
Re: Question about function aliases
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: 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); } 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);
Re: Question about function aliases
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
Re: Question about function aliases
On Thursday, 12 December 2013 at 11:11:55 UTC, bearophile wrote: 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 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.
Re: Question about function aliases
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); }