Ruby和Swig:TypeError:can';t将nil转换为字符串

Ruby和Swig:TypeError:can';t将nil转换为字符串,ruby,swig,libqxt,Ruby,Swig,Libqxt,作为问题的后续行动: 我正试图在ruby中使用(即) 正如:我创建了包装器,但是当尝试使用生成的库时,我遇到了错误: irb(main):005:0> shortcut = QxtGlobalShortcut::QxtGlobalShortcut.new ui TypeError: can't convert nil into String from (irb):5:in `initialize' from (irb):5:in `new' from (irb):5

作为问题的后续行动:

我正试图在ruby中使用(即)

正如:我创建了包装器,但是当尝试使用生成的库时,我遇到了错误:

irb(main):005:0> shortcut = QxtGlobalShortcut::QxtGlobalShortcut.new ui
TypeError: can't convert nil into String
    from (irb):5:in `initialize'
    from (irb):5:in `new'
    from (irb):5
    from /usr/bin/irb:12:in `<main>'
有关swig生成的输出,请参阅:

知道怎么修吗? 谢谢

更新:

基于@PascalHurni扩展日志差异提供irb输出:

$ irb
irb(main):001:0> require 'Qt4'
=> true
irb(main):002:0> require 'QxtGlobalShortcut'
=> true
irb(main):003:0> app = Qt::Application.new ARGV                                                                                                                   
=> #<Qt::Application:0x00000001d79d98 objectName="irb">                                                                                                           
irb(main):004:0> ui = Qt::Widget.new                                                                                                                              
=> #<Qt::Widget:0x00000001f16818 objectName="", x=0, y=0, width=640, height=480>                                                                                  
irb(main):005:0> shortcut = QxtGlobalShortcut::QxtGlobalShortcut.new ui                                                                                           
_wrap_new_QxtGlobalShortcut ENTERING with 0 arguments                                                                                                             
TypeError: can't convert nil into String
    from (irb):5:in `initialize'
    from (irb):5:in `new'
    from (irb):5
    from /usr/bin/irb:12:in `<main>'
有什么想法吗

更新2:

基于@PascalHurni扩展日志差异(版本2)提供irb输出:

$irb
irb(主):001:0>要求“Qt4”
=>正确
irb(主):002:0>要求“QxtGlobalShortcut”
=>正确
irb(主):003:0>app=Qt::Application.new ARGV
=> #
irb(main):004:0>ui=Qt::Widget.new
=> #
irb(main):005:0>快捷方式=QxtGlobalShortcut::QxtGlobalShortcut.new ui
_用1个参数换行\u new\u QxtGlobalShortcut输入
_在ptr转换之前换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行0类型=12
TypeError:无法将nil转换为字符串
发件人(irb):5:在“初始化”中
发件人(irb):5:在“new”中
来自(irb):5
from/usr/bin/irb:12:in`'

这一个比较棘手。我没有看到任何对字符串的引用,因此TypeError非常奇怪

尽管如此,您仍可以使用此要点修补生成的.cxx文件。如您所见,它只是添加了一组
printf()
,以跟踪对
#initialize
的调用。你可以按照这个模式来追踪它,也许用更多的信息编辑你的问题,或者更新irb会话(显示跟踪)

更新

简而言之,您生成的Qxt库和使用的Qt-ruby库似乎不是由同一版本的SWIG生成的。这对于分离的lib来说不是问题,但是因为Qxt lib将与Qt lib进行互操作(您将作为Qt包装对象的ui参数传递给您自己的Qxt包装对象),所以两者都必须由相同版本(至少是次要版本?)的SWIG包装

回到技术细节: 引发的异常来自于在第1984行上调用
SWIG\u ConvertPtr
,它依次调用
SWIG\u Ruby\u MangleStr
。此函数尝试在传递的参数上获取实例变量
@\uu swigtype\uu
,该参数在代码中为
ui
。这是能够键入传递的参数(C++侧)。这个变量似乎是
nil
(因为它来自于Qt,但没有使用这样的变量),而
SWIG\u Ruby\u MangleStr
中的代码希望将其转换为字符串

结论: 我不知道如何确定哪个版本的SWIG包装了一个现有的lib,如果你找到一个,你可能会得到一个包装了Qt lib的版本,并使用该版本包装你的Qxt lib


另一种方法是使用已知版本的SWIG生成Qt库,并对Qxt库执行相同的操作。

感谢您的帮助。我只是尝试了扩展日志记录。请参阅更新的问题。我用更多的跟踪更新了要点,并修复了argc问题(我的错误)。您是否可以重新编译并运行此修补程序(针对原始文件)并替换问题中更新的输出。请注意,您的问题出现得很早,因为我们只在SWIG调度功能中。从这里看来,传递的参数可能具有错误的类型(您的ui ruby参数),但这似乎很奇怪。
#ifndef QXTGLOBALSHORTCUT_H
#define QXTGLOBALSHORTCUT_H

#include "qxtglobal.h"
#include <QObject>
#include <QKeySequence>

class QxtGlobalShortcut : public QObject
{

public:
    explicit QxtGlobalShortcut(QObject* parent);
    explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0);
    virtual ~QxtGlobalShortcut();

    QKeySequence shortcut() const;
    bool setShortcut(const QKeySequence& shortcut);

    bool isEnabled() const;

};

#endif // QXTGLOBALSHORTCUT_H
$ cat QxtGlobalShortcut.i
%module QxtGlobalShortcut
%{
/* Includes the header in the wrapper code */
#include "/usr/include/QxtGui/QxtGlobalShortcut"
%}

/* Parse the header file to generate wrappers */
%include "qxtglobalshortcut.h"

$ cat extconf.sh
require 'mkmf'
dir_config('QxtCore')
dir_config('QxtGui')
dir_config('QtCore')
dir_config('QtGui')
create_makefile('QxtGlobalShortcut')

$ cat wrapper.sh
swig -c++ -ruby QxtGlobalShortcut.i
ruby extconf.rb --with-QxtCore-include=/usr/include/QxtCore/ --with-QxtGui-include=/usr/include/QxtGui/ --with-QtCore-include=/usr/include/QtCore/ --with-QtGui-include=/usr/include/QtGui/
make 
sudo make install
$ irb
irb(main):001:0> require 'Qt4'
=> true
irb(main):002:0> require 'QxtGlobalShortcut'
=> true
irb(main):003:0> app = Qt::Application.new ARGV                                                                                                                   
=> #<Qt::Application:0x00000001d79d98 objectName="irb">                                                                                                           
irb(main):004:0> ui = Qt::Widget.new                                                                                                                              
=> #<Qt::Widget:0x00000001f16818 objectName="", x=0, y=0, width=640, height=480>                                                                                  
irb(main):005:0> shortcut = QxtGlobalShortcut::QxtGlobalShortcut.new ui                                                                                           
_wrap_new_QxtGlobalShortcut ENTERING with 0 arguments                                                                                                             
TypeError: can't convert nil into String
    from (irb):5:in `initialize'
    from (irb):5:in `new'
    from (irb):5
    from /usr/bin/irb:12:in `<main>'
creating Makefile
g++ -I. -I/usr/include/x86_64-linux -I/usr/include/ruby/backward -I/usr/include -I. -I/usr/include/QtGui/ -I/usr/include/QtCore/ -I/usr/include/QxtGui/ -I/usr/include/QxtCore/    -fPIC -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -mtune=generic -fPIC -m64 -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -mtune=generic -o QxtGlobalShortcut_wrap.o -c QxtGlobalShortcut_wrap.cxx
QxtGlobalShortcut_wrap.cxx: In function ‘void SWIG_Ruby_define_class(swig_type_info*)’:
QxtGlobalShortcut_wrap.cxx:1517:9: warning: variable ‘klass’ set but not used [-Wunused-but-set-variable]
QxtGlobalShortcut_wrap.cxx: In function ‘void SWIG_InitializeModule(void*)’:
QxtGlobalShortcut_wrap.cxx:2206:21: warning: statement has no effect [-Wunused-value]
QxtGlobalShortcut_wrap.cxx: In function ‘VALUE _wrap_new_QxtGlobalShortcut(int, VALUE*, VALUE)’:
QxtGlobalShortcut_wrap.cxx:1973:75: warning: ‘argc’ is used uninitialized in this function [-Wuninitialized]
rm -f QxtGlobalShortcut.so
g++ -shared -o QxtGlobalShortcut.so QxtGlobalShortcut_wrap.o -L. -L/usr/lib64 -L. -Wl,-z,relro -rdynamic -Wl,-export-dynamic  -m64  -lruby  -lpthread -lrt -ldl -lcrypt -lm   -lc
/usr/bin/mkdir -p /usr/local/lib64/ruby/site_ruby
/usr/bin/install -c -m 0755 QxtGlobalShortcut.so /usr/local/lib64/ruby/site_ruby
$ irb
irb(main):001:0> require 'Qt4'
=> true
irb(main):002:0> require 'QxtGlobalShortcut'
=> true
irb(main):003:0> app = Qt::Application.new ARGV 
=> #<Qt::Application:0x000000017b4e30 objectName="irb">
irb(main):004:0> ui = Qt::Widget.new
=> #<Qt::Widget:0x00000001952940 objectName="", x=0, y=0, width=640, height=480>
irb(main):005:0> shortcut = QxtGlobalShortcut::QxtGlobalShortcut.new ui
_wrap_new_QxtGlobalShortcut ENTERING with 1 arguments
_wrap_new_QxtGlobalShortcut before ptr convert for _wrap_new_QxtGlobalShortcut__SWIG_0 TYPE=12
TypeError: can't convert nil into String
    from (irb):5:in `initialize'
    from (irb):5:in `new'
    from (irb):5
    from /usr/bin/irb:12:in `<main>'