Re: Question about function aliases

2013-12-17 Thread Gary Willoughby

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

2013-12-12 Thread Gary Willoughby

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

2013-12-12 Thread bearophile

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

2013-12-12 Thread FreeSlave

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

2013-12-11 Thread dnewbie
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);
}