www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Passing class instance as void* and casting back

reply Maxim Fomin <maxim maxim-fomin.ru> writes:
Hello. I use curl library and need to overwrite default behavior of
data/headers writing.
I use

   curl_easy_setopt(curl, CurlOption.headerfunction, &header_func);
   curl_easy_setopt(curl, CurlOption.writeheader, &this);

where "this" is a class Inet instance, and header_func is a static
function of the class
(should be a callback of fwrite() args semantics). The class has
buffer for header_func
which should copy data from char *ptr to the buffer.
In
   private static size_t header_func(char *ptr, size_t size, size_t
nmemb, void *userdata)
object is casted back:
   Inet *net = cast(Inet*)userdata;
However, I receive segfault at the beginning of header_func().
I don't know how dmd compiler treats object references.
I tried to pass just "this" (without taking address) and cast without
* and all 4 combinations
of &this/this, cast(Inet*)/cast(Inet); none of them works (segfault on
access to Inet class).

So, how can I pass an object through void* or may be there is another
way to tell
header_func() which object should be used?

Thanks.

P.S. D is a nice language, it's a pleasant to work with)
Nov 05 2011
next sibling parent reply Jonas Drewsen <jdrewsen nospam.com> writes:
Den 05-11-2011 09:38, Maxim Fomin skrev:
 Hello. I use curl library and need to overwrite default behavior of
 data/headers writing.

 So, how can I pass an object through void* or may be there is another
 way to tell
 header_func() which object should be used?

You can use this working curl wrapper (from phobos review 2) as inspiration. /Jonas
Nov 05 2011
parent Jonas Drewsen <jdrewsen nospam.com> writes:
Den 05-11-2011 21:00, Jonas Drewsen skrev:
 Den 05-11-2011 09:38, Maxim Fomin skrev:
 Hello. I use curl library and need to overwrite default behavior of
 data/headers writing.

 So, how can I pass an object through void* or may be there is another
 way to tell
 header_func() which object should be used?

You can use this working curl wrapper (from phobos review 2) as inspiration. /Jonas

And the link ;) https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl.d
Nov 05 2011
prev sibling parent Benjamin Thaut <code benjamin-thaut.de> writes:
Am 05.11.2011 09:38, schrieb Maxim Fomin:
 Hello. I use curl library and need to overwrite default behavior of
 data/headers writing.
 I use

     curl_easy_setopt(curl, CurlOption.headerfunction,&header_func);
     curl_easy_setopt(curl, CurlOption.writeheader,&this);

 where "this" is a class Inet instance, and header_func is a static
 function of the class
 (should be a callback of fwrite() args semantics). The class has
 buffer for header_func
 which should copy data from char *ptr to the buffer.
 In
     private static size_t header_func(char *ptr, size_t size, size_t
 nmemb, void *userdata)
 object is casted back:
     Inet *net = cast(Inet*)userdata;
 However, I receive segfault at the beginning of header_func().
 I don't know how dmd compiler treats object references.
 I tried to pass just "this" (without taking address) and cast without
 * and all 4 combinations
 of&this/this, cast(Inet*)/cast(Inet); none of them works (segfault on
 access to Inet class).

 So, how can I pass an object through void* or may be there is another
 way to tell
 header_func() which object should be used?

 Thanks.

 P.S. D is a nice language, it's a pleasant to work with)

If you cast the void* to a INet when recieving it you should also cast it to a INet when passing it to curl. Pointers to classes point at the same address as any parent class they inherit from. Interfaces however might point into the middle of a class, thus the address of a interface reference is different then the address of a class reference. Classes and interfaces are references types in D so there is no need to use the address operator. Correct would be something like: INet callback = this; curl_easy_setopt(curl, CurlOption.headerfunction, &header_func); curl_easy_setopt(curl, CurlOption.writeheader, callback); ... void header_func(...) { INet callback = cast(INet)userdata; ... } -- Kind Regards Benjamin Thaut
Nov 07 2011