Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 11, 2013 callback parameter order question | ||||
---|---|---|---|---|
| ||||
Hi, I try to create a D interface to GNU Libmicrohttpd because i could not find any, and while i was implementing a demo webserver i've noticed that the MHD_AccessHandlerCallback in D is triggered with the parameters in the reverse order. This is in c: struct MHD_Daemon * MHD_start_daemon (unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls, ...); typedef int (*MHD_AccessHandlerCallback) (void *cls, struct MHD_Connection * connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls); and to work in D I had to this: alias int function(void **con_cls, size_t *upload_data_size, const char *upload_data, const char *ver, const char *method, const char *url, MHD_Connection* connection, void* cls) MHD_AccessHandlerCallback; extern (C) { ..... MHD_Daemon *MHD_start_daemon(uint flags, uint port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...); .... } Can anyone help me to understand this? Thanks, Bogdan |
May 11, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to gedaiu | On 5/11/13, gedaiu <szabobogdan@yahoo.com> wrote:
> alias int function(void **con_cls,
> size_t *upload_data_size,
> const char *upload_data,
> const char *ver,
> const char *method,
> const char *url,
> MHD_Connection* connection,
> void* cls) MHD_AccessHandlerCallback;
Add extern(C) to the alias:
alias extern(C) int function(void **con_cls, ...) MHD_AccessHandlerCallback;
|
May 11, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Saturday, 11 May 2013 at 09:39:42 UTC, Andrej Mitrovic wrote: > On 5/11/13, gedaiu <szabobogdan@yahoo.com> wrote: >> alias int function(void **con_cls, >> size_t *upload_data_size, >> const char *upload_data, >> const char *ver, >> const char *method, >> const char *url, >> MHD_Connection* connection, >> void* cls) MHD_AccessHandlerCallback; > > Add extern(C) to the alias: > > alias extern(C) int function(void **con_cls, ...) MHD_AccessHandlerCallback; if i do that, i get this error src/import/server.d(128): Error: function gnu.microhttpd.MHD_start_daemon (uint flags, uint port, extern (C) int function(void* cls, const(sockaddr*) addr, uint addrlen) apc, void* apc_cls, extern (C) int function(void* cls, MHD_Connection* connection, const(char*) url, const(char*) method, const(char*) ver, const(char*) upload_data, ulong* upload_data_size, void** con_cls) dh, void* dh_cls, ...) is not callable using argument types (MHD_FLAG,int,typeof(null),typeof(null),int function(void* cls, MHD_Connection* connection, const(char*) url, const(char*) method, const(char*) ver, const(char*) upload_data, ulong* upload_data_size, void** ptr) @system,typeof(null),MHD_OPTION) src/import/server.d(128): Error: cannot implicitly convert expression (ahc_echo) of type int function(void* cls, MHD_Connection* connection, const(char*) url, const(char*) method, const(char*) ver, const(char*) upload_data, ulong* upload_data_size, void** ptr) @system to extern (C) int function(void* cls, MHD_Connection* connection, const(char*) url, const(char*) method, const(char*) ver, const(char*) upload_data, ulong* upload_data_size, void** con_cls) |
May 11, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to gedaiu | On 5/11/13, gedaiu <szabobogdan@yahoo.com> wrote:
> if i do that, i get this error
I don't know what "ahc_echo" is, but I imagine you'll have to make it
an extern(C) function.
|
May 11, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Saturday, 11 May 2013 at 10:04:54 UTC, Andrej Mitrovic wrote: > On 5/11/13, gedaiu <szabobogdan@yahoo.com> wrote: >> if i do that, i get this error > > I don't know what "ahc_echo" is, but I imagine you'll have to make it > an extern(C) function. Hi, i have this code, and i don't think i can add extern(C) there void start() { auto ahc_echo = function(void* cls, MHD_Connection* connection, const char *url, const char *method, const char *ver, const char *upload_data, size_t *upload_data_size, void **ptr) { ... }; d = MHD_start_daemon(MHD_FLAG.MHD_USE_THREAD_PER_CONNECTION, 8080, null, null, ahc_echo, null, MHD_OPTION.MHD_OPTION_END); } and if i create a function like this: extern(C) int ahc_echo(void* cls, MHD_Connection* connection, const char *url, const char *method, const char *ver, const char *upload_data, size_t *upload_data_size, void **ptr) { .... }; i get this error: Error: function cmsutils.CMServer.ahc_echo (void* cls, MHD_Connection* connection, const(char*) url, const(char*) method, const(char*) ver, const(char*) upload_data, ulong* upload_data_size, void** ptr) is not callable using argument types () Error: expected 8 function arguments, not 0 |
May 11, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to gedaiu | On Saturday, 11 May 2013 at 10:44:01 UTC, gedaiu wrote: > On Saturday, 11 May 2013 at 10:04:54 UTC, Andrej Mitrovic wrote: >> On 5/11/13, gedaiu <szabobogdan@yahoo.com> wrote: >>> if i do that, i get this error >> >> I don't know what "ahc_echo" is, but I imagine you'll have to make it >> an extern(C) function. > > Hi, > > > i have this code, and i don't think i can add extern(C) there > > void start() { > > auto ahc_echo = function(void* cls, > MHD_Connection* connection, > const char *url, > const char *method, > const char *ver, > const char *upload_data, > size_t *upload_data_size, > void **ptr) { > ... > }; > > d = MHD_start_daemon(MHD_FLAG.MHD_USE_THREAD_PER_CONNECTION, 8080, null, null, ahc_echo, null, MHD_OPTION.MHD_OPTION_END); > > } > > > and if i create a function like this: > > > extern(C) int ahc_echo(void* cls, > MHD_Connection* connection, > const char *url, > const char *method, > const char *ver, > const char *upload_data, > size_t *upload_data_size, > void **ptr) { > .... > }; > > > i get this error: > Error: function cmsutils.CMServer.ahc_echo (void* cls, MHD_Connection* connection, const(char*) url, const(char*) method, const(char*) ver, const(char*) upload_data, ulong* upload_data_size, void** ptr) is not callable using argument types () > > Error: expected 8 function arguments, not 0 looks like you are trying to pass func as parameter in this func, but you forgot to take its address d = MHD_start_daemon(MHD_FLAG.MHD_USE_THREAD_PER_CONNECTION, 8080, null, null, &ahc_echo, // <-- here null, MHD_OPTION.MHD_OPTION_END); |
May 11, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to gedaiu | On 5/11/13, gedaiu <szabobogdan@yahoo.com> wrote:
> i have this code, and i don't think i can add extern(C) there
That's a problem with the parser. Instead of auto use the actual function type:
alias extern(C) int function(void **con_cls,
size_t *upload_data_size,
const char *upload_data,
const char *ver,
const char *method,
const char *url,
MHD_Connection* connection,
void* cls) MHD_AccessHandlerCallback;
...
MHD_AccessHandlerCallback ahc_echo = function(void* cls,
MHD_Connection* connection,
const char *url,
const char *method,
const char *ver,
const char *upload_data,
size_t *upload_data_size,
void **ptr) {
...
};
|
May 11, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to evilrat | On Saturday, 11 May 2013 at 11:28:10 UTC, evilrat wrote:
> On Saturday, 11 May 2013 at 10:44:01 UTC, gedaiu wrote:
>> On Saturday, 11 May 2013 at 10:04:54 UTC, Andrej Mitrovic wrote:
>>> On 5/11/13, gedaiu <szabobogdan@yahoo.com> wrote:
>>>> if i do that, i get this error
>>>
>>> I don't know what "ahc_echo" is, but I imagine you'll have to make it
>>> an extern(C) function.
>>
>> Hi,
>>
>>
>> i have this code, and i don't think i can add extern(C) there
>>
>> void start() {
>>
>> auto ahc_echo = function(void* cls,
>> MHD_Connection* connection,
>> const char *url,
>> const char *method,
>> const char *ver,
>> const char *upload_data,
>> size_t *upload_data_size,
>> void **ptr) {
>> ...
>> };
>>
>> d = MHD_start_daemon(MHD_FLAG.MHD_USE_THREAD_PER_CONNECTION, 8080, null, null, ahc_echo, null, MHD_OPTION.MHD_OPTION_END);
>>
>> }
>>
>>
>> and if i create a function like this:
>>
>>
>> extern(C) int ahc_echo(void* cls,
>> MHD_Connection* connection,
>> const char *url,
>> const char *method,
>> const char *ver,
>> const char *upload_data,
>> size_t *upload_data_size,
>> void **ptr) {
>> ....
>> };
>>
>>
>> i get this error:
>> Error: function cmsutils.CMServer.ahc_echo (void* cls, MHD_Connection* connection, const(char*) url, const(char*) method, const(char*) ver, const(char*) upload_data, ulong* upload_data_size, void** ptr) is not callable using argument types ()
>>
>> Error: expected 8 function arguments, not 0
>
> looks like you are trying to pass func as parameter in this func, but you forgot to take its address
>
> d = MHD_start_daemon(MHD_FLAG.MHD_USE_THREAD_PER_CONNECTION, 8080, null, null, &ahc_echo, // <-- here
> null, MHD_OPTION.MHD_OPTION_END);
yeah... what a shameful mistake.. i vave a new tricky question... how i can provide a class method instead a simple function as callback?
|
May 11, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to gedaiu | On 05/11/2013 10:34 AM, gedaiu wrote: > how i can provide a class method instead a simple function as > callback? Can you describe a little bit more? Where will the object that the member function will be called on come from? Do you want to use always the same object that you already have up front, or do you want to create a new object when the member function needs to be called? In any case, you will have to use a delegate. Ali |
May 12, 2013 Re: callback parameter order question | ||||
---|---|---|---|---|
| ||||
Posted in reply to gedaiu | On Saturday, 11 May 2013 at 17:34:53 UTC, gedaiu wrote:
>
> yeah... what a shameful mistake.. i vave a new tricky question... how i can provide a class method instead a simple function as callback?
with D code use delegates as Ali commented, it's simple. with C code use static method and pass instance pointer as callback target, something like this
---------------
// C function
alias extern(C) function(void*) callbackfunc;
extern(C) setCallback(callbackfunc cb, void* userptr);
class Handler {
static extern(C) callback(void* instance) {
if ( auto self = cast(Handler) instance )
self.onCallback();
}
void onCallback() {
// ...
// your code here
// ...
}
}
void setCAPI_callback(Handler hnd) {
setCallback(Handler.callback, hnd); // don't remember if needed to cast hnd to void
}
however this would require C API which has userptr argument in callbacks(hopefully most libs i've seen has this)
|
Copyright © 1999-2021 by the D Language Foundation