On 23. Apr, 2010, at 8:06 , Michael Wild wrote:

> 
> On 22. Apr, 2010, at 20:43 , Jan Hudec wrote:
> 
>> On Thu, Apr 22, 2010 at 11:47:21 +0200, Michael Wild wrote:
>>> 1) Constructor function: Say I would like to use a C function as the
>>> constructor for a class (as e.g. newwin is used in curses.vapi). However,
>>> that C function does not return the allocated and initialized object in the
>>> return value, but as the first argument. The return value is an error code
>>> instead. How would I handle this?
>> 
>> I believe you'll have to declare it as a static function and wrap it as
>> constructor in the .vapi itself.
>> 
>> I suppose you have a function like:
>> 
>> int thing_init(Thing **self, int param);
>> 
>> (allocate+return by reference implies pointer-to-pointer, right?)
>> 
>> Than in the class you first declare the function itself, like
>> 
>> class Thing {
>>   private static init(out Thing self, int param);
>> 
>> Than you need to define the constructor, which is where I am a bit lost.
>> It does work for normal methods, but constructor is a bit special.
>> I would guess this might work:
>> 
>>   public Thing(int param) throws ThingError {
>>      int status = init(this, param);
>>      if(status != 0)
>>          throw new ThingError.FAILED(
>>              "Thing construction failed with status %d", status);
>>   }
>> 
>> But I am not sure whether you need to initialize this or create normal
>> variable and return it or employ some other trick. Maybe defining another
>> static function and than rebinding it as constructor. Something like
>> 
>>   public static Thing new(int param) throws ThingError {
>>      Thing self;
>>      int status = init(self, param);
>>      ...
>>      return self;
>>   }
>>   public Thing(int param) throws (ThingError);
>> 
>> You'll have to play with it a bit.
>> 
>> Note, that I made it throw an error. I assume if it returns an error code,
>> you'll want to get it somehow and since the allocated object is the return
>> value, an exception is the only option.
> 
> Thanks, I was stumbling along the same lines. However, now I'm stuck because 
> I can't convince Vala to generate the C-code for the static functions in the 
> .vapi file.
> 
> 
> Michael


Looking at gnutls.vapi I noticed that there the same problem exists. Instead of 
binding it to a constructor, static create() methods are used to wrap the 
C-functions. I'm probably going to do the same.

Another thing where I'm not sure how to best solve it: The basic C-type I'm 
using is a typedef to a pointer whose base-type is implementation dependent 
(i.e. unknown). E.g. like this:

typedef struct unknown_type* Thing;

Now, in my small test cases, I used the following for the binding:

[SimpleType]
[CCode (cname = "Thing", cheader_filename = "thing.h", free_function = "free")]
struct Thing {
  [CCode (cname = "create_thing")]
  private static int create_imp(Thing* self, int a, int b, double c); 
  [CCode (cname = "create_thing_wrapper")]
  public static Thing create(int a, int b, double c) {
    Thing self;
    int stat = create_imp(&self, a, b, c); 
    return self;
  }
  
  [CCode (cname = "print_thing")]
  public void print();
}

This compiles and runs, but Vala now (quite understandably) thinks that Thing 
is a value-type and doesn't call free() on it. AFAIK for this to happen I'd 
need to change Thing to be a of compact class type, but then everything else 
would break because Vala starts passing the object around as a pointer (i.e. 
resulting in unknonw_type**, where unknown_type* is expected).

Michael
_______________________________________________
vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to