Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
December 11, 2013 Question about function aliases | ||||
---|---|---|---|---|
| ||||
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? |
December 12, 2013 Re: Question about function aliases | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | 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);
}
|
December 12, 2013 Re: Question about function aliases | ||||
---|---|---|---|---|
| ||||
Posted in reply to dnewbie | 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); |
December 12, 2013 Re: Question about function aliases | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | 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 |
December 12, 2013 Re: Question about function aliases | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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.
|
December 17, 2013 Re: Question about function aliases | ||||
---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | 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.
|
Copyright © 1999-2021 by the D Language Foundation