From: Bernhard Brodowsky Date: 2012-08-30T16:34:16+09:00 Subject: Re: Common Traps for C extensions Robert Klemme wrote in post #1073869: > On Wed, Aug 29, 2012 at 8:08 PM, Bernhard Brodowsky > wrote: >> Hi, I am writing a toy library in C++ and currently, I am writing a Ruby >> extensions for it. >> >> I have one C++ layer to catch all the C++ exceptions, convert them into >> error codes wich casts the void Pointers it gets from C to the >> appropriate classes etc. Then I have one C layer which handles the Ruby >> datatypes and raises the correct exceptions. > > Wouldn't it be simpler to implement just one layer of C++ functions > with extern "C" that do all the adjustments (i.e. catch C++ exceptions > and convert types)? > >> But now I am thinking of possible traps I might run into. For example, >> the Ruby interpreter forces me to differentiate between allocation and >> initialization and in my current implementation, the User could redefine >> the initialize() method of my class and then call another method, which >> results in undefined behaviour or possibly segfault. > > I am not sure I understand the scenario. Are you talking about a user > redefining #initialize in Ruby land leading to improperly initialized > C / C++ data structures? > >> I can easily solve >> that problem (e.g. by setting some internal flag) but there are probably >> a thousand other typical traps like that, where the dynamicity of Ruby >> messes with my C memory management. Do you know any important others? > > I never did serious C extension coding so I can't help you with > general guidelines. Storing something which verifies integrity of the > C++ data structures is certainly a good idea. If I think about it, > isn't it sufficient to check whether a pointer to the C++ struct is > valid, i.e. not NULL? It certainly depends on how you design the > interface between Ruby and C / C++ world: you could completely rely on > C / C++ state or make use of Ruby instance variables from C / C++ > which would probably make things more complicated. > > Kind regards > > robert Hi, thanks for your answer. Somehow it didn't compile as C++ code, if I do the conversions, so I just thought it is not possible and divided it into one part that is compiled as C++ with extern C functions and one part that is compiled as C. Exactly, that is what I am talking about, checking for non-null does not suffice, because Ruby calls my alloc function first, so the pointer is actually valid, but it points to an uninitialized object. -- Posted via http://www.ruby-forum.com/.