SWIG:如何包装一个引用 int64_t 作为参数的函数?
SWIG: how to wrap a function that takes reference to int64_t as parameter?
我的界面文件TestRef.i
:
%module test_ref
%{
#include <iostream>
%}
%include <stdint.i>
%include <typemaps.i>
%inline %{
struct Result {
uint64_t len;
void* data;
};
Result read(int64_t& idx) {
std::cout << idx << std::endl; // just to use idx
idx++;
return Result{1, nullptr};
}
void set_value(double& a) {
a = 42.;
}
%}
%apply int64_t& INOUT { int64_t& idx };
%apply double& INOUT { double& a };
void set_value(double& a);
我的目标是通过引用参数调用 read()
,其中 returns 一个 C 结构(实际打包)和一个 int64_t。
这是我的构建方式:
$ swig -python -c++ -I/usr/include TestRef.i
$ g++ -fPIC -c TestRef_wrap.cxx -I/opt/rh/rh-python38/root/usr/include/python3.8 -std=c++17 -O3
$ g++ -shared TestRef_wrap.o -o _test_ref.so -lrt
这是我得到的错误:
>>> import test_ref
>>> idx = 1000
>>> p = test_ref.read(idx)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/hc/test/cpp/test_ref.py", line 79, in read
return _test_ref.read(idx)
TypeError: in method 'read', argument 1 of type 'int64_t &'
一些 post 建议将“返回”引用,所以我应该这样做:
>>> p, idx = test_ref.read(idx)
但同样的错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/hc/test/cpp/test_ref.py", line 79, in read
return _test_ref.read(idx)
TypeError: in method 'read', argument 1 of type 'int64_t &'
然后,我找到了这个post。
我试过了(TestRef.i
上面已经包含 set()
):
>>> a = 0.0
>>> a = set_value(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/hc/test/cpp/test_ref.py", line 66, in set_value
return _test_ref.set_value(a)
TypeError: in method 'set_value', argument 1 of type 'double &'
我正在使用 SWIG 4.0。
据此post,[t]he typemap must also be declared before SWIG parses test
。
将我的 TestRef.i
更改为
%module test_ref
%{
#include <iostream>
%}
%include <stdint.i>
%include <typemaps.i>
%apply int64_t& INOUT { int64_t& idx };
%apply double& INOUT { double& a };
%inline %{
struct Result {
uint64_t len;
void* data;
};
Result read(int64_t& idx) {
std::cout << idx << std::endl; // just to use idx
idx++;
return Result{1, nullptr};
}
void set(double& a) {
a = 42.;
}
作品:
>>> import test_ref
>>> idx = 1024
>>> p, idx = test_ref.read(idx)
1024
>>> print(idx)
1025
>>>
我的界面文件TestRef.i
:
%module test_ref
%{
#include <iostream>
%}
%include <stdint.i>
%include <typemaps.i>
%inline %{
struct Result {
uint64_t len;
void* data;
};
Result read(int64_t& idx) {
std::cout << idx << std::endl; // just to use idx
idx++;
return Result{1, nullptr};
}
void set_value(double& a) {
a = 42.;
}
%}
%apply int64_t& INOUT { int64_t& idx };
%apply double& INOUT { double& a };
void set_value(double& a);
我的目标是通过引用参数调用 read()
,其中 returns 一个 C 结构(实际打包)和一个 int64_t。
这是我的构建方式:
$ swig -python -c++ -I/usr/include TestRef.i
$ g++ -fPIC -c TestRef_wrap.cxx -I/opt/rh/rh-python38/root/usr/include/python3.8 -std=c++17 -O3
$ g++ -shared TestRef_wrap.o -o _test_ref.so -lrt
这是我得到的错误:
>>> import test_ref
>>> idx = 1000
>>> p = test_ref.read(idx)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/hc/test/cpp/test_ref.py", line 79, in read
return _test_ref.read(idx)
TypeError: in method 'read', argument 1 of type 'int64_t &'
一些 post 建议将“返回”引用,所以我应该这样做:
>>> p, idx = test_ref.read(idx)
但同样的错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/hc/test/cpp/test_ref.py", line 79, in read
return _test_ref.read(idx)
TypeError: in method 'read', argument 1 of type 'int64_t &'
然后,我找到了这个post。
我试过了(TestRef.i
上面已经包含 set()
):
>>> a = 0.0
>>> a = set_value(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/hc/test/cpp/test_ref.py", line 66, in set_value
return _test_ref.set_value(a)
TypeError: in method 'set_value', argument 1 of type 'double &'
我正在使用 SWIG 4.0。
据此post,[t]he typemap must also be declared before SWIG parses test
。
将我的 TestRef.i
更改为
%module test_ref
%{
#include <iostream>
%}
%include <stdint.i>
%include <typemaps.i>
%apply int64_t& INOUT { int64_t& idx };
%apply double& INOUT { double& a };
%inline %{
struct Result {
uint64_t len;
void* data;
};
Result read(int64_t& idx) {
std::cout << idx << std::endl; // just to use idx
idx++;
return Result{1, nullptr};
}
void set(double& a) {
a = 42.;
}
作品:
>>> import test_ref
>>> idx = 1024
>>> p, idx = test_ref.read(idx)
1024
>>> print(idx)
1025
>>>