SWIG: mapping a typedef array

I use SWIG to create a Ruby Wrapper for some C ++ classes. This is the signature of the C ++ method, which is causing me problems:

virtual LogP wordProb(VocabIndex word, const VocabIndex *context);

This is the definition of VocabIndex:

#ifdef USE_SHORT_VOCAB
typedef unsigned short  VocabIndex;
#else
typedef unsigned int    VocabIndex;
#endif

So I call it a Ruby script:

index = 8
context = [index]
puts ngram.wordProb(index, context)

This is the error I get when I run my script:

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>'

My decision taken :

After reading the docs (yes, I am using SWIG 2.0), I tried this in the .i file:

%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);

The swig command worked fine, but when I tried to create a wrapper library, I got the following:

NgramWrapper_wrap.cxx:148:17: fatal error: tcl.h: No such file or directory
 #include <tcl.h>

So, I started the terminal (this is the Ubuntu field) and ran:

sudo apt-get install tcl-dev

Installed tcl 8.6, which placed its header files in a directory /usr/include/tcl8.6. So I added that include the directory in the Makefile line that creates 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 ? ...

+4
1

.

vocal.i

%module rubylm

%{
#include "Ngram.h"
%}

%include "Ngram.h"
%include "typemaps.i"

virtual LogP Ngram::wordProb(VocabIndex word, const VocabIndex *INPUT);

Ngram.h

#pragma once

#ifdef USE_SHORT_VOCAB
typedef unsigned short  VocabIndex;
#else
typedef unsigned int    VocabIndex;
#endif

typedef int LogP;

class NGram {
 public:
  LogP wordProb(VocabIndex word, const VocabIndex *context);
};

swig2.0 -ruby -c++ vocal.i

g++ -c vocal_wrap.cxx -I/usr/include/ruby-2.1.0 -I/usr/include/x86_64-linux-gnu/ruby-2.1.0

. -++ tcl.h

+2

Source: https://habr.com/ru/post/1608253/


All Articles