Swig:处理简化界面的最佳方式
Swig : best way to handle a simplified interface
我们使用Swig向Python公开了一组C++类。我们经常在方法中添加新的参数。另一方面,我们有一组Python脚本,我们希望尽可能容易地维护这些脚本。因此,当我们在C++中更改公开方法的参数集时,我们不希望必须更改所有使用此方法的python脚本。为此,我们为每个C++类创建了一个辅助接口类(C++类也是),它拥有一个指向原始类实例的指针,并公开了一个简化的接口。
例如,假设我们有一个方法为foo:的类a
class A {
public :
void foo (int a, int b, double c, char * d, ....);
};
假设我们只对python中的a、b和c参数感到满意(将默认值传递给其他参数)。
我们创建了一个APy类
class APy {
public :
void foo(int a,int b, double c) {
A->foo(a,b,c,default,default,...);
}
protected :
A * ref;
};
其优点是可以向A::foo添加新参数,更改参数顺序和方法名称,更常见的是,对于更复杂的更改,可以在不更改现有Python脚本的情况下编写原始方法的等效代码。此外,如果脚本需要一个新的参数,可以通过APy::foo中的默认参数添加它,而不必在原始的a::foo方法中这样做。
缺点是,由于有两个对象,因此处理删除很困难。当APy被销毁时,我们应该删除A吗?这取决于情况。有时A是较大对象的内部对象,不应被破坏。但是只要APy不再被Python脚本使用,它就应该被销毁。
我想知道是否有可能通过直接映射原始类和方法,但要求swig映射并简化参数列表本身,来设计一个更简单但同样方便的体系结构。
在.i文件中,是否可以要求Swig更改参数的顺序,为未公开的参数设置默认值(而不是.h默认值)?
例如,如果我有一个函数
void foo(int a, double b, int c);
我想在脚本语言中只保留a和c的相反顺序,并将b设置为10.0
所以,当我打电话给时
foo(3, 5)
它实际上会被映射到:
foo(5,10.0,3)
不管怎样,我很想听听你的经验,你认为处理这些问题的最佳方法是什么。
我认为您可以通过SWIG的%ignore
、%rename
和%extend
指令来很好地解决您的问题。有关详细信息,请查阅SWIG文档。但是对于上面的例子,您可以使用以下接口文件:
%module example
%{
#define SWIG_FILE_WITH_INIT
%}
%ignore A::foo(int a, double b, int c);
%inline %{
class A {
public :
double foo(int a, double b, int c) {
return a * b - c;
}
};
%}
%extend A {
double foo(int c, int a) {
return $self->foo(a, 10.0, c);
}
};
(请注意,如果您在头文件中声明了函数,那么您当然也可以使用%{ #include "example.h" %}
和%include "example.h"
来代替%inline %{ ... %}
。)
使用这种方法,无论何时更改C++代码,都需要更新SWIG接口文件,但您应该能够自定义暴露于Python的API。
还有一个技巧你应该知道,即你可以指示%ignore
匹配更多,例如所有方法或A::foo
的所有版本。但是,在使用%extend
之前,您需要先"unignore"它们。因此,这里有一个稍微复杂/高级的例子来展示这个(标准SWIG)技巧:
%module example
%{
#define SWIG_FILE_WITH_INIT
%}
%ignore A::foo;
%inline %{
class A {
public :
double foo(int a, double b, int c) {
return a * b - c;
}
double foo(int a, double b) {
return a * b;
}
};
%}
%rename("%s") A::foo;
%extend A {
int foo(int c, int a) {
return $self->foo(a, 10.0, c);
}
};
同样,请查看SWIG文档以了解确切的详细信息。
- 在c代码之间共享数据的最佳方式
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 在reactor中存储eventHandlers的最佳方式是什么
- 在AVX通道中混洗的最佳方式
- 从 T 创建 std::future 的最佳方式<T>
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- 对列表列表中的元素进行分组的最佳方式
- 利用 GPU 的最佳方式
- 使用 QT C++过滤大数据的最佳方式
- 算法设计:用边界数字表示 2D 网格的最佳方式,以C++?
- 在C++中共享键值对的最佳方式
- 为Catch2中的外部文本文件指定路径的最佳方式
- 代表Quarto棋盘游戏棋子的最佳方式
- 等待线程的最佳方式是什么
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 创建控制台菜单C++的最佳方式
- 只显示片段着色器的最佳方式是什么
- 复制文件的最佳方式是什么,以便我可以在复制过程中轻松取消复制?