www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Question about function aliases

reply "Gary Willoughby" <dev nomad.so> writes:
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
parent reply "dnewbie" <run3 myopera.com> writes:
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
parent reply "Gary Willoughby" <dev nomad.so> writes:
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);
Dec 12 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
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
parent reply "FreeSlave" <freeslave93 gmail.com> writes:
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.
Dec 12 2013
parent "Gary Willoughby" <dev nomad.so> writes:
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