Code Monkey home page Code Monkey logo

ffi-swig-generator's Issues

Swig %rename(...) not being respected

If I use %rename() in a Swig .i file, the resultant XML has the new identifiers in the sym_name attributes (and the original names in the name attributes). But ffi-swig-generator keeps the original names, despite the fact that FFI's attach_function() can take an alternative name.

A one-line change to lib/generator/function.rb can fix this:

diff --git a/lib/generator/function.rb b/lib/generator/function.rb
index 8a26dd2..1483485 100644
--- a/lib/generator/function.rb
+++ b/lib/generator/function.rb
@@ -21,7 +21,7 @@ module FFI
         params = get_params(@node).inject([]) do |array, node|
           array << Argument.new(:node => node, :typedefs => @typedefs).to_s
         end
-        @indent_str + "attach_function :#{@symname}, [ #{params.join(', ')} ], #{get_rtype}"
+        @indent_str + "attach_function :#{get_attr('sym_name')}, :#{@symname}, [ #{params.join(', ')} ], #{get_rtype}"
       end
       private
       def get_params(node)

String constants are generated without quotes

If my header file has this:

#define FOO "foo"

Then the generated ruby file has this:

FOO = foo

In other words, foo is not quoted.

I think that adding the following to the case statement in the sanitize! method in Constant will address this (though not certain about nested quotes)

when 'p.char'
      result = "\"#{@value}\""

Enum types using :int instead of Enum class

When generating ruby for the following code:

enum test_enum { FIRST, SECOND, THIRD };
struct test_struct {
  enum test_enum test_value;
}

ffi-gen outputs the following ffi struct:

class TestStruct < FFI::Struct
  layout(
    :test_enum, :int,
  )
end

It should generate the following struct instead:

class TestStruct < FFI::Struct
  layout(
    :test_enum, TestStruct,
  )
end

Function with va_list type argument

Not sure how this can be handled, but basically this function

void fn(const char *fmt, va_list vl);

swig generates as

<cdecl id="4456" addr="0x6efce8" >
                <attributelist id="4457" addr="0x6efce8" >
                    <attribute name="sym_name" value="fn" id="4458" addr="0xbf61b8" />
                    <attribute name="name" value="fn" id="4459" addr="0xbf61b8" />
                    <attribute name="decl" value="f(p.q(const).char,va_list)." id="4460" addr="0xbf61b8" />
                    <parmlist id="4461" addr="0x6efad8" >
                        <parm id="4462">
                            <attributelist id="4463" addr="0x6efc08" >
                                <attribute name="name" value="fmt" id="4464" addr="0xbf61b8" />
                                <attribute name="type" value="p.q(const).char" id="4465" addr="0xbf61b8" />
                            </attributelist >
                        </parm >
                        <parm id="4466">
                            <attributelist id="4467" addr="0x6efc98" >
                                <attribute name="name" value="vl" id="4468" addr="0xbf61b8" />
                                <attribute name="type" value="va_list" id="4469" addr="0xbf61b8" />
                            </attributelist >
                        </parm >
                    </parmlist >
                    <attribute name="kind" value="function" id="4470" addr="0xbf61b8" />
                    <attribute name="type" value="void" id="4471" addr="0xbf61b8" />
                    <attribute name="sym_symtab" value="0x6d0468" id="4472" addr="0x6d0468" />
                    <attribute name="sym_overname" value="__SWIG_0" id="4473" addr="0xbf61b8" />
                </attributelist >
</cdecl >

and it shows as

attach_function :fn, :fn, [ :string, va_list ], :void

which will fail with undefined local variable or method 'va_list'

I think currently could just comment it out or set va_list as :pointer. If someone really wants to use this, then I guess va_list type needs to be implemented in Ruby FFI

Typedefs for opaque structs being generated incorrectly

Given the following opaque struct definition:

struct opaque_struct;
typedef struct opaque_struct opaque_struct;

We get the following output

typedef OpaqueStruct.by_value, :opaque_struct

The FFI typedef command does not support this. It also does not support the following syntax:

typedef OpaqueStruct, :opaque_struct

In the case of opaque structs, no typedef line should be generated.

Typedef'ed structs result in invalid arguments and struct members

Given the following C code:

typedef struct typedefed_struct {
  int i;
  char c;
} typedefed_struct;

struct other_struct {
  typedefed_struct s;
  int i;
};

int func(typedefed_struct *s);

ffi-swig-generator outputs the following Ruby code:

  class TypedefedStruct < FFI::Struct
    layout(
           :i, :int,
           :c, :char
    )
  end
  class OtherStruct < FFI::Struct
    layout(
           :s, :typedefed_struct,
           :i, :int
    )
  end
  attach_function :func, :func, [ :pointer ], :int

This code results in an error from ffi, `TypeError: unable to resolve type 'typedefed_struct'.

ffi-swig-generator should instead generate the following code:

  class TypedefedStruct < FFI::Struct
    layout(
           :i, :int,
           :c, :char
    )
  end
  class OtherStruct < FFI::Struct
    layout(
           :s, TypedefedStruct.by_value,
           :i, :int
    )
  end
  attach_function :func, :func, [ TypedefedStruct.ptr ], :int

ffi-swig generating a :string instead of a :pointer

See: http://groups.google.com/group/ruby-ffi/browse_thread/thread/98eaf51ab0386347

I have a C++ function that takes a pointer to a buffer where the function stores a C-string.

This is what I wrote and got working.

attach_function :GoIO_GetNthAvailableDeviceName, [:pointer, :int, :int, :int, :int], :int

However if I use ffi-swig it generates a :string as the first parameter.

attach_function :GoIO_GetNthAvailableDeviceName, [ :string, :int, :int, :int, :int ], :int

Is there anyway this could work? The function needs an address to a location to store a C-string.

Here's the C++ function:

GOIO_DLL_INTERFACE_DECL gtype_int32 GoIO_GetNthAvailableDeviceName(
  char *pBuf,            // [out] ptr to buffer to store device name string.
  gtype_int32 bufSize,   // [in] number of bytes in buffer pointed to by pBuf.
                         // Strlen(pBuf) < bufSize, because the string is NULL terminated.
  gtype_int32 vendorId,  // [in] USB vendor id
  gtype_int32 productId, //[in] USB product id
  gtype_int32 N);        //[in] index into list of known devices, 0 => first device in list.

Looking more closely at ffi-swig it's type_spec.rb does expect:

char *string;

to be turned into a :string.

I'm not much of a C programmer but is that correct? It seems in this case it should be a pointer.

Types like these are correctly turned into :string

const char *string;

The choice about turning a pointer into a string appears to be made in ffi-swig at lib/generator/type.rb:74:

def pointer
  if @declaration.is_pointer? or @is_pointer > 0
    @is_pointer += 1
    if @full_decl.scan(/^p\.(.+)/).flatten[0]
      ffi_type_from(@full_decl.scan(/^p\.(.+)/).flatten[0])
    elsif @full_decl == 'char' and @is_pointer == 2
      ':string'
    else
      ':pointer'
    end
  end       
end

CLI: ffi-gen --version (-v) -> uninitialized constant FFI::Generator::VERSION

ffi-gen -v

/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2503:in const_missing': uninitialized constant FFI::Generator::VERSION (NameError) from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/lib/generator/application.rb:39:indo_option'
from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/lib/generator/application.rb:48:in process_args' from /usr/lib/ruby/1.8/getoptlong.rb:613:ineach'
from /usr/lib/ruby/1.8/getoptlong.rb:610:in loop' from /usr/lib/ruby/1.8/getoptlong.rb:610:ineach'
from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/lib/generator/application.rb:48:in process_args' from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/lib/generator/application.rb:22:inrun'
from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/bin/ffi-gen:6
from /usr/bin/ffi-gen:19:in load' from /usr/bin/ffi-gen:19 localhost:~ # ffi-gen --version /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2503:inconst_missing': uninitialized constant FFI::Generator::VERSION (NameError)
from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/lib/generator/application.rb:39:in do_option' from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/lib/generator/application.rb:48:inprocess_args'
from /usr/lib/ruby/1.8/getoptlong.rb:613:in each' from /usr/lib/ruby/1.8/getoptlong.rb:610:inloop'
from /usr/lib/ruby/1.8/getoptlong.rb:610:in each' from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/lib/generator/application.rb:48:inprocess_args'
from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/lib/generator/application.rb:22:in run' from /usr/lib/ruby/gems/1.8/gems/ffi-swig-generator-0.3.2/bin/ffi-gen:6 from /usr/bin/ffi-gen:19:inload'
from /usr/bin/ffi-gen:19

Array as function argument

When I've callback defined as

#define COUNT 10
void (*cl)(int list[COUNT]);

swig produces

<attribute name="decl" value="f(a(COUNT).int)." id="19616" addr="0xbf61b8" />

and it appears

callback([ a(COUNT).int ], :void)

but it probably should be

callback([ [:int, 10] ], :void)

only that's not supported yet, see ffi/ffi#385

callbacks not working after 14ea222

It appears commit 14ea222 broke callbacks.

Using the following input file:

%module Test
typedef void (*myfunc) (int foo);

With commit 818e921 I get the following result:

  Callback_myfunc = callback(:myfunc, [ :int ], :void)

With commit 14ea222 (and up to current master -- a018380) I get an empty file.

unnamed enums

Hi!
I have this code:

typedef enum week {
   SUNDAY,
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY
} week;

and I'm expecting that generator will create named enum:

 week = enum(
      :sunday,
      :monday,
      :tuesday,
      :wednesday,
      :thursday,
      :friday,
      :saturday)

but it doesn't:

MONDAY = 0
TUESDAY = 1
...

Is it possible to fix it?

Typedefs for pointers to opaque structs

A typedef for a pointer to an opaque struct results in invalid ruby being generated.

Given the following C code:

typedef struct opaque_struct* opaque_pointer;
opaque_pointer func(void);

ffi-swig-generator outputs the following ruby:

attach_function :func, :func, [  ], :opaque_pointer

The line defining the :opaque_pointer as a :pointer is missing. The output should be as follows:

typedef :pointer, :opaque_pointer
attach_function :func, :func, [  ], :opaque_pointer

Pointers to opaque structures do not work with attach_function()

Given the following C code:

struct opaque_struct;
struct opaque_struct *alloc_opaque_struct(void);

We currently generate the following ruby code:

class OpaqueStruct < FFI::Struct; end
attach_function :alloc_opaque_struct, :alloc_opaque_struct, [  ], OpaqueStruct.ptr

This code fails when calling alloc_opaque_struct() because FFI references the layout of the struct, which is not defined.

Instead, the following code should be generated:

attach_function :alloc_opaque_struct, :alloc_opaque_struct, [  ], :pointer

Resolution of callback names in JRuby and MRI 1.9

Consider the C code below:

typedef void (*MyCallback) (void *data);
typedef struct {
  void (*member) (MyCallback cb);
} MyStruct;

Using the generator you get:

callback(:MyCallback, [ :pointer ], :void)
class MyStruct < FFI::Struct
  layout(
    :member, callback([ :MyCallback ], :void)
  )
end

The ruby code above works fine on MRI 1.8 but not on JRuby or MRI 1.9.

The best way to ensure this works is to generate a constant in enclosing module, and use that on the layout line.

module Foo
  extend FFI::Library
  MyCallback = callback(:MyCallback, [ :pointer ], :void
  class MyStruct < FFI::Struct
    layout(:member, callback(MyCallback, :void))
  end
end

Incorrect function pointer arguments within argument

Given the following code:

int cvStartLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]);

ffi-swig-generator outputs the following, invalid, ruby code:

attach_function :cvStartLoop, :cvStartLoop, [ callback([ :int, a().p.char ], :int), :int, :pointer ], :pointer

Note the a().p.char as the second argument within the callback.

ffi-swig-generator should output:

attach_function :cvStartLoop, :cvStartLoop, [ callback([:int, :pointer], :int), :int, :pointer ], :pointer

Enum values initialized with other enum members cause non-functional code.

Minimal Example:

%module test
%{
module Test
%}
enum foo {
FOO,
BAR = FOO
};
%{
end
%}

Generates to

module Test
  foo = enum :foo, [
    :foo,
    :bar, FOO, // fails here, obviously
  ]
  FOO = 0
  BAR = FOO
end

which doesn't work. I am not completely sure that ffi-swig-generator is at fault here, but it is my best idea.

Pointer typedefs generated incorrectly

Pointer typedefs are not being generated correctly. Given the following c typedef:

typedef int * pInt

This is the ruby code that is generated:

typedef :int, :pInt

This is what should be generated:

typedef :pointer, :pInt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.