digitalmars.D.learn - callback parameter order question
- gedaiu (42/42) May 11 2013 Hi,
- Andrej Mitrovic (3/11) May 11 2013 Add extern(C) to the alias:
- gedaiu (22/34) May 11 2013 if i do that, i get this error
- Andrej Mitrovic (3/4) May 11 2013 I don't know what "ahc_echo" is, but I imagine you'll have to make it
- gedaiu (35/40) May 11 2013 Hi,
- evilrat (6/47) May 11 2013 looks like you are trying to pass func as parameter in this func,
- gedaiu (4/66) May 11 2013 yeah... what a shameful mistake.. i vave a new tricky question...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (7/9) May 11 2013 Can you describe a little bit more? Where will the object that the
- evilrat (25/28) May 11 2013 with D code use delegates as Ali commented, it's simple. with C
- Andrej Mitrovic (21/22) May 11 2013 That's a problem with the parser. Instead of auto use the actual functio...
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
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
On Saturday, 11 May 2013 at 09:39:42 UTC, Andrej Mitrovic wrote:On 5/11/13, gedaiu <szabobogdan yahoo.com> wrote: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)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
On 5/11/13, gedaiu <szabobogdan yahoo.com> wrote:if i do that, i get this errorI don't know what "ahc_echo" is, but I imagine you'll have to make it an extern(C) function.
May 11 2013
On Saturday, 11 May 2013 at 10:04:54 UTC, Andrej Mitrovic wrote:On 5/11/13, gedaiu <szabobogdan yahoo.com> wrote: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 0if i do that, i get this errorI don't know what "ahc_echo" is, but I imagine you'll have to make it an extern(C) function.
May 11 2013
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: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);On 5/11/13, gedaiu <szabobogdan yahoo.com> wrote: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 0if i do that, i get this errorI don't know what "ahc_echo" is, but I imagine you'll have to make it an extern(C) function.
May 11 2013
On Saturday, 11 May 2013 at 11:28:10 UTC, evilrat wrote:On Saturday, 11 May 2013 at 10:44:01 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?On Saturday, 11 May 2013 at 10:04:54 UTC, Andrej Mitrovic wrote: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);On 5/11/13, gedaiu <szabobogdan yahoo.com> wrote: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 0if i do that, i get this errorI don't know what "ahc_echo" is, but I imagine you'll have to make it an extern(C) function.
May 11 2013
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 11 2013
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)
May 11 2013
On 5/11/13, gedaiu <szabobogdan yahoo.com> wrote:i have this code, and i don't think i can add extern(C) thereThat'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