Question

I want to create a basic ruby module for xcb for my own use. I tried a basic test where I wrap header file with swig: here is my xcb_ruby.i

%module ruxcby 
%{
#include <xcb/xcb.h>
#include <xcb/xcb_util.h>
#include <xcb/xcb_aux.h
#include <xcb/xcb_atom.h>
#include <xcb/xcb_event.h>
%}
%include "/usr/include/xcb/xproto.h"
%include "/usr/include/xcb/xcb.h"
%include "/usr/include/xcb/xcb_atom.h"
%include "/usr/include/xcb/xcb_aux.h"
%include "/usr/include/xcb/xcb_event.h"

When I try it in irb, I am able to connect to initialize connection, get information from this connection but the ruby interface is like in C. I would like to have a more object oriented interface.

For example in xcb.h there is :

typedef struct xcb_connection_t xcb_connection_t;
xcb_connection_t * xcb_connect(const char *displayname, int *screenp);
int xcb_flush( xcb_connection_t *);
uint32_t xcb_generate_id( xcb_connection_t *);
void xcb_disconnect(xcb_connection_t * );

I want to have a Connection class with methods new/connect(), flush(), generate_id() and disconnect() here is my new xcb_ruby.i:

%module ruxcby
%{
#include <xcb/xcb.h>
#include <xcb/xproto.h>
%}
%import "/usr/include/xcb/xproto.h"

typedef struct xcb_connection_t {
} Connection;

%extend Connection 
{
  Connection(const char *displayname, int *screenp)
  {
    Connection * c;
    c = xcb_connect(displayname, screenp);
    return c;
  }
  int flush()
  {
    return xcb_flush($self);
  }
  xcb_generic_event_t *wait_for_event()
  {
    return xcb_wait_for_event($self);
  }
  void disconnect()
  {
    return xcb_disconnect($self);
  }
  uint32_t generate_id()
  {
    return xcb_generate_id($self);
  }
};

If I try to compile after I have generated the c file, I have an error: erreur: unknown type name ‘Connection’

Can someone tell me where I am wrong?

Thanks

Edits

I have made some modifications and now I can compile it but I still get some errors:

%module ruxcby
%{
#include <xcb/xcb.h>
#include <xcb/xproto.h>
typedef struct {
  xcb_connection_t * ptr;
} Connection;
%}
%import "/usr/include/xcb/xproto.h"
%feature("autodoc" , "1");

typedef struct {
  xcb_connection_t * ptr;
} Connection;
%extend Connection {
  Connection(const char *displayname, int *screenp)
 {
    Connection * c ;
    c->ptr = xcb_connect(displayname, screenp);
    return c;
 }
 int flush()
 {  
    return xcb_flush($self->ptr);
 }
 xcb_generic_event_t *wait_for_event()
 {
    return xcb_wait_for_event($self->ptr);
 }
 int connection_has_error()
 {
    return xcb_connection_has_error($self->ptr);
 }
 void disconnect()
 {
   return xcb_disconnect($self->ptr);
 }
 uint32_t generate_id()
 {
    return xcb_generate_id($self->ptr);
 }
};

Now I can compile my module and use it:

require './ruxcby'
=> true
conn=Connection.new(nil, nil)
=> #<Ruxcby::Connection:0x0000000223dfc8>

But when I try another method I have an error:

conn.connection_has_error 
ObjectPreviouslyDeleted: Expected argument 0 of type Connection *, but got Ruxcby::Connection #<Ruxcby::

It seems that the method exist but there is still a problem when passing argument to the method.

Any ideas??

Était-ce utile?

La solution

I put the solution maybe it can help someone: When I extend the Connection class I didn't allocated memory for my structure:

%extend Connection {
Connection(const char *displayname, int *screenp)
{
  Connection * c ;
  c = (Connection * ) malloc(sizeof(Connection));
  c->ptr = xcb_connect(displayname, screenp);
  return c;
}
~Connection()
{
  free($self);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top