我正在使用SWIG爲一些C++類創建一個Ruby包裝器。這是這是給我找麻煩了C++方法的簽名:SWIG:映射typedef的數組
virtual LogP wordProb(VocabIndex word, const VocabIndex *context);
這是VocabIndex的定義:
#ifdef USE_SHORT_VOCAB
typedef unsigned short VocabIndex;
#else
typedef unsigned int VocabIndex;
#endif
這是我從Ruby腳本調用的方式:
index = 8
context = [index]
puts ngram.wordProb(index, context)
這是我得到的錯誤,當我運行我的腳本:
ngram.rb:26:in `wordProb': Expected argument 2 of type VocabIndex const *, but got Array [8] (TypeError)
in SWIG method 'wordProb'
from ngram.rb:26:in `<main>'
我嘗試的解決方案:
看完後的docs(是的,我使用痛飲2.0),我在.i文件試過這樣:
%module rubylm
%{
#include "srilm-1.7.1/lm/src/Ngram.h"
%}
%include "srilm-1.7.1/lm/src/Counts.h"
%include "srilm-1.7.1/lm/src/Ngram.h"
%include "typemaps.i"
virtual LogP Ngram::wordProb(VocabIndex word, const VocabIndex *INPUT);
的痛飲命令運行正常,但是當我試圖建立的包裝庫,我得到這個:
NgramWrapper_wrap.cxx:148:17: fatal error: tcl.h: No such file or directory
#include <tcl.h>
所以我啓動了一個終端(這是一個Ubuntu盒),跑:
sudo apt-get install tcl-dev
安裝了tcl 8.6,它將頭文件放在/usr/include/tcl8.6
目錄中。所以,我補充說,包括Makefile行它建立NgramWrapper_wrap.o目錄:
NgramWrapper_wrap.o: NgramWrapper_wrap.cxx
$(CC) $(CFLAGS) NgramWrapper_wrap.cxx -I $(RUBY_SRC) -I $(MISC_INCLUDE) -I $(DSTRUCT_INCLUDE) -I /usr/include/tcl8.6
不過,我仍然得到編譯錯誤。這裏是我被困住的地方:
NgramWrapper_wrap.cxx:10812:34: error: ‘RARRAY_LEN’ was not declared in this scope
int size = RARRAY_LEN(objv[3]);
^
NgramWrapper_wrap.cxx:10816:5: error: ‘VALUE’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10816:12: error: ‘ptr’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10816:36: error: ‘RARRAY_PTR’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10819:35: error: ‘StringValuePtr’ was not declared in this scope
arg3[i]= StringValuePtr(*ptr);
^
NgramWrapper_wrap.cxx: In function ‘int _wrap_NgramCountWrapper_run(ClientData, Tcl_Interp*, int, Tcl_Obj* const*)’:
NgramWrapper_wrap.cxx:10908:34: error: ‘RARRAY_LEN’ was not declared in this scope
int size = RARRAY_LEN(objv[3]);
^
NgramWrapper_wrap.cxx:10912:5: error: ‘VALUE’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10912:12: error: ‘ptr’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10912:36: error: ‘RARRAY_PTR’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10915:35: error: ‘StringValuePtr’ was not declared in this scope
arg3[i]= StringValuePtr(*ptr);
我能想到的是Ruby,Swig和Tcl之間的一些版本不匹配。但是我怎麼知道使用哪個Tcl版本?我搜索文檔無濟於事...
Carrays.i是快速解決方案:http://www.swig.org/Doc2.0/Library.html#Library_carrays更多的紅寶石知識比我有更聰明的做法。 – Flexo
如果我嘗試使用carrays。我,當我嘗試使用typemaps.i時遇到了相同的構建錯誤。我的Ruby-Swig-Tcl組合中有些問題。我現在所能想出的就是降級Tcl。要嘗試一下。 –