From: Andreas L. <no...@sb...> - 2001-05-27 18:06:28
|
I will remove the make_pointer_ features from C_STRING_HELPER, rename make_ to new_ and unify the class using GEPP as you suggested. I think the class needs a better name. Do you have an idea? When I am ready, I can post it here, so you can include it into GOBO as soon as UCSTRING gets merged into GOBO. Is that ok with you? On 27 May 2001 11:27:16 +0200, Eric Bezault wrote: > Andreas Leitner wrote: [snip] > In the version of C_STRING_HELPER_NP for ISE Eiffel you > wrote: > > make_pointer_from_string (s: STRING): POINTER is > -- returns the pointer to the data of a specific string > -- does this work with a moving gc?? > > make_pointer_from_string_buffer (data: SPECIAL [CHARACTER]): POINTER > is > -- returns the pointer to the data of a specific string > -- does this work with a moving gc?? > > the answer is no: it is not safe when using a moving GC and > you might get weird behaviors. The only safe way to pass > pointers to Eiffel objects to C code is to use directly the > $ construct in the arguments of the external routines. So > I would suggest that you put all your external routines in > a class *_EXTERNALS along with routines without POINTERs > as arguments or results, and that you put this class in > clusters spec/[ise|se|ve|hact] (you can possibly use 'gepp'). > For example if you have an external C routine such as: > > char *foo (char *str) {} > > I would suggest that you have the following routines in your > *_EXTERNALS class: > > feature -- Something here > > foo (str: STRING): STRING is > -- ... > require > str_not_void: str /= Void > local > c_str: ANY > do > !! Result.make (0) > c_str := str.to_c > Result.from_c (c_foo ($c_str)) > ensure > foo_not_void: Result /= Void > end > > feature {NONE} -- Externals > > c_foo (str: POINTER): POINTER is > -- ... > require > str_not_null: str /= default_pointer > external > "C" > alias > "...." > ensure > c_foo_not_null: Result /= default_pointer > end > > and provide different implementations for the different Eiffel > compilers. This is in my opinion the only safe way with respect > to moving GC to implement calls to C functions with pointers > to Eiffel objects. > > It may look cumbersome at first, but it is actually cleaner > because the public interface of this class does not involve > POINTER, only pure Eiffel types. So if one day expat is > ported to .Net or JVM you will have less work to do since > the only class aware of the C language will be this class. Removing all POINTERS does not make sense, because sometimes (for expat actually most of the time) POINTER is not a C string, but some other pointer. It may be a pointer to a structure, but it may also be just a void* (that in C-library intern may very well a pointer to a struct again) but the user cannot and should not know. For the user it is just a handle (like the handle to the expat parser, or the handle to a window in a GUI toolkit). I will remove all pointers which are in fact some sort of char* in the feature arguments and provide three features instead: ext_foo (s: POINTER) is external ... foo_string (s: STRING) is do ... foo_string_buffer (s: like STRING_BUFFER_TYPE) is do ... I can totaly leave the POINTERs in the function results, because on the C side there is no moving GC and in case the POINTER really is a char* I can use new_string_from_c_zero_terminted_string. regards, Andreas |