Can't figure out method signature...
grimmy opened this issue · comments
Any help in this would be greatly appreciated. I'm trying to call into a library of mine that works in other languages with the given gir, I just can't seem to figure out the syntax to make it right or if it's even supported. My knowledge of ruby is very poor, so I have tried a bunch of different combinations and can't seem to get it right.
Currently I'm running 0.7.7. I saw you just released 0.7.8 but it's not in Debian SID yet but I'll compile it if you think it'll help...
$ dpkg -s ruby-gir-ffi | grep Version
Version: 0.7.7-1
Anyways here's the run down... I have a two functions in my library defined as follows
/**
* gplugin_plugin_info_new: (skip)
* @id: The id of the plugin
* @abi_version: The GPlugin ABI version that the plugin uses
* @...: name/value pairs of properties to set, followed by %NULL.
*
* Creates a new GPluginPluginInfo instance.
*
* Returns: The new GPluginPluginInfo instance.
*/
GPluginPluginInfo *
gplugin_plugin_info_new(const gchar *id, guint32 abi_version, ...) {
...
}
/**
* gplugin_plugin_info_newv: (rename-to gplugin_plugin_info_new)
* @id: The id of the plugin
* @abi_version: The GPlugin ABI version that the plugin uses
* @n_parameters: the length of the @parameters array
* @parameters: (array length=n_parameters): an array of #GParameter
*
* Creates a new GPluginPluginInfo instance.
*
* Returns: (type GPlugin.PluginInfo) (transfer full): The new
* GPluginPluginInfo instance.
*/
GPluginPluginInfo *
gplugin_plugin_info_newv(const gchar *id, guint32 abi_version,
guint n_parameters, GParameter *parameters)
{
...
}
In the gir it looks like
<constructor name="new"
c:identifier="gplugin_plugin_info_new"
shadowed-by="newv"
introspectable="0">
<doc xml:space="preserve">Creates a new GPluginPluginInfo instance.</doc>
<return-value transfer-ownership="full">
<doc xml:space="preserve">The new GPluginPluginInfo instance.</doc>
<type name="PluginInfo" c:type="GPluginPluginInfo*"/>
</return-value>
<parameters>
<parameter name="id" transfer-ownership="none">
<doc xml:space="preserve">The id of the plugin</doc>
<type name="utf8" c:type="const gchar*"/>
</parameter>
<parameter name="abi_version" transfer-ownership="none">
<doc xml:space="preserve">The GPlugin ABI version that the plugin uses</doc>
<type name="guint32" c:type="guint32"/>
</parameter>
<parameter name="..." transfer-ownership="none">
<doc xml:space="preserve">name/value pairs of properties to set, followed by %NULL.</doc>
<varargs/>
</parameter>
</parameters>
</constructor>
<constructor name="newv"
c:identifier="gplugin_plugin_info_newv"
shadows="new">
<doc xml:space="preserve">Creates a new GPluginPluginInfo instance.</doc>
<return-value transfer-ownership="full">
<doc xml:space="preserve">The new
GPluginPluginInfo instance.</doc>
<type name="PluginInfo" c:type="GPluginPluginInfo*"/>
</return-value>
<parameters>
<parameter name="id" transfer-ownership="none">
<doc xml:space="preserve">The id of the plugin</doc>
<type name="utf8" c:type="const gchar*"/>
</parameter>
<parameter name="abi_version" transfer-ownership="none">
<doc xml:space="preserve">The GPlugin ABI version that the plugin uses</doc>
<type name="guint32" c:type="guint32"/>
</parameter>
<parameter name="n_parameters" transfer-ownership="none">
<doc xml:space="preserve">the length of the @parameters array</doc>
<type name="guint" c:type="guint"/>
</parameter>
<parameter name="parameters" transfer-ownership="none">
<doc xml:space="preserve">an array of #GParameter</doc>
<array length="2" zero-terminated="0" c:type="GParameter*">
<type name="GObject.Parameter" c:type="GParameter"/>
</array>
</parameter>
</parameters>
</constructor>
I have tried a ton of different ways to actually create an instance with no success...
return GPlugin::PluginInfo.new(
'ruby/ruby-basic-plugin',
0x01020304,
{:name => 'basic plugin'}
)
Results in
/usr/lib/ruby/vendor_ruby/gir_ffi/struct_base.rb:26:in `copy_value_to_pointer': undefined method `to_ptr' for [:name, "basic plugin"]:Array (NoMethodError)
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:87:in `block in from_struct_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `each'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `each_with_index'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `from_struct_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:19:in `from_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/sized_array.rb:83:in `from_enumerable'
from /usr/lib/ruby/vendor_ruby/gir_ffi/sized_array.rb:69:in `from'
from (eval):6:in `new'
from /usr/lib/ruby/vendor_ruby/gir_ffi/class_base.rb:37:in `setup_and_call'
from (eval):2:in `new'
from basic.rb:6:in `gplugin_query'
from basic.rb:28:in `<main>'
return GPlugin::PluginInfo.new(
'ruby/ruby-basic-plugin',
0x01020304,
:name => 'basic plugin'
)
Results in
/usr/lib/ruby/vendor_ruby/gir_ffi/struct_base.rb:26:in `copy_value_to_pointer': undefined method `to_ptr' for [:name, "basic plugin"]:Array (NoMethodError)
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:87:in `block in from_struct_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `each'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `each_with_index'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `from_struct_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:19:in `from_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/sized_array.rb:83:in `from_enumerable'
from /usr/lib/ruby/vendor_ruby/gir_ffi/sized_array.rb:69:in `from'
from (eval):6:in `new'
from /usr/lib/ruby/vendor_ruby/gir_ffi/class_base.rb:37:in `setup_and_call'
from (eval):2:in `new'
from basic.rb:6:in `gplugin_query'
from basic.rb:28:in `<main>'
return GPlugin::PluginInfo.new(
:id=>'ruby/ruby-basic-plugin',
:abi_version=>0x01020304,
:name => 'basic plugin'
)
Results in
(eval):1:in `new': wrong number of arguments (1 for 3) (ArgumentError)
from /usr/lib/ruby/vendor_ruby/gir_ffi/class_base.rb:37:in `setup_and_call'
from (eval):2:in `new'
from basic.rb:6:in `gplugin_query'
from basic.rb:28:in `<main>'
return GPlugin::PluginInfo.new(
'ruby/ruby-basic-plugin',
0x01020304,
["name", "basic plugin"]
)
Results in
/usr/lib/ruby/vendor_ruby/gir_ffi/struct_base.rb:26:in `copy_value_to_pointer': undefined method `to_ptr' for "name":String (NoMethodError)
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:87:in `block in from_struct_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `each'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `each_with_index'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `from_struct_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:19:in `from_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/sized_array.rb:83:in `from_enumerable'
from /usr/lib/ruby/vendor_ruby/gir_ffi/sized_array.rb:69:in `from'
from (eval):6:in `new'
from /usr/lib/ruby/vendor_ruby/gir_ffi/class_base.rb:37:in `setup_and_call'
from (eval):2:in `new'
from basic.rb:6:in `gplugin_query'
from basic.rb:28:in `<main>'
And
return GPlugin::PluginInfo.new(
'ruby/ruby-basic-plugin',
0x01020304,
[{:name => "basic plugin"}]
)
Results in
/usr/lib/ruby/vendor_ruby/gir_ffi/struct_base.rb:26:in `copy_value_to_pointer': undefined method `to_ptr' for {:name=>"basic plugin"}:Hash (NoMethodError)
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:87:in `block in from_struct_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `each'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `each_with_index'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:86:in `from_struct_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/in_pointer.rb:19:in `from_array'
from /usr/lib/ruby/vendor_ruby/gir_ffi/sized_array.rb:83:in `from_enumerable'
from /usr/lib/ruby/vendor_ruby/gir_ffi/sized_array.rb:69:in `from'
from (eval):6:in `new'
from /usr/lib/ruby/vendor_ruby/gir_ffi/class_base.rb:37:in `setup_and_call'
from (eval):2:in `new'
from basic.rb:6:in `gplugin_query'
from basic.rb:28:in `<main>'
Hi @grimmy,
GirFFI currently doesn't automatically convert hashes to GParameters. This means you would have to provide an array of GObject::Parameter
objects, which is a rather tedious affair. For most classes this is not a problem, since the class-specific constructors don't take GParameters.
Can you tell me which other languages you have tried and how you would call new
there?
Python that's using py-gobject
from gi.repository import GPlugin
def gplugin_query():
return GPlugin.PluginInfo(
id='gplugin/python-basic-plugin',
abi_version=0x01020304,
name='basic plugin',
authors=['author1'],
category='test',
version='version',
license_id='license',
summary='summary',
website='website',
description='description',
)
def gplugin_load(plugin):
return True
def gplugin_unload(plugin):
return True
print gplugin_query()
$ python basic.py
<PluginInfo object at 0x7f8849436b40 (GPluginPluginInfo at 0x19f50a0)>
Lua using lgi
local lgi = require 'lgi'
local GPlugin = lgi.GPlugin
function gplugin_query()
return GPlugin.PluginInfo {
id = "gplugin/lua-basic-plugin",
abi_version = 0x01020304,
name = "basic plugin",
category = "test",
version = "version",
license_id = "license",
summary = "summary",
description = "description",
authors = { "author1" },
website = "website"
}
end
function gplugin_load(plugin)
return true
end
function gplugin_unload(plugin)
return true
end
print(gplugin_query())
$ lua basic.lua
lgi.obj 0x148d890:GPlugin.PluginInfo(GPluginPluginInfo)
Thanks! That'll help me figure out how this should work in GirFFI.
For the record, it looks like the default constructor for lua and python just call g_object_new using a dictionary as the params. I added gplugin_plugin_info_new and gplugin_plugin_info_newv to try and make gir-ffi figure it out.
Well, just started looking at this again with someone and turns out it's working now, so yay! :-D