使用swig将python与c++对接

[✔]c++向python通信
[✔]python向c++传递矩阵

下附swig如何传递矩阵

C/C++辅助函数

可以通过辅助函数来完一些SWIG本身不支持的功能。事实上,辅助函数可谓SWIG包装的瑞士军刀,一旦了解它使用,你可以使SWIG支持几乎所有你需要的功能,不过提醒一下,有很多C++特性是SWIG本身支持或者通过库支持的,不需要通过辅助函数实现。

同样的,直接上例示代码:
 void set_transform(Image *im, double m[4][4]);
 
 a = [ ... [1,0,0,0], ... [0,1,0,0], ... [0,0,1,0], ... [0,0,0,1]]
 set_transform(im,a) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 
 Type error. Expected _p_a_4__double
可以看到,set_transform是不能接受Python二维List的,可以用辅助函数帮助实现:
%inline %{
    /* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */
    double (*new_mat44())[4] {
    return (double (*)[4]) malloc(16*sizeof(double)); } void free_mat44(double (*x)[4]) {
    free(x); } void mat44_set(double x[4][4], int i, int j, double v) {
    x[i][j] = v; } double mat44_get(double x[4][4], int i, int j) {
    return x[i][j]; } 
 %}


    a = new_mat44()
    mat44_set(a,0,0,1.0)
    mat44_set(a,1,1,1.0)
    mat44_set(a,2,2,1.0) ...
    set_transform(im,a)

当然,这样使用起来还不够优雅,但可以工作了,接下来介绍通过插入额外的Python代码来让使用优雅起来。

插入额外的Python代码

为了让set_transform函数接受Python二维list或tuple,我们可以对它的Python代码稍加改造:

void set_transform(Image *im, double x4);

... / Rewrite the high level interface to set_transform /

%pythoncode %{
   def set_transform(im,x):
   a = new_mat44()
   for i in range(4):
   for j in range(4):
   mat44_set(a,i,j,x[i][j])
   _example.set_transform(im,a)
   free_mat44(a) 
%}

 a = [ ... [1,0,0,0], ... [0,1,0,0], ... [0,0,1,0], ... [0,0,0,1]]  
 set_transform(im,a)
Last modification:June 7th, 2020 at 10:18 pm
如果觉得我的文章对你有用,请随意赞赏