本文介绍了Python C包装器,用于读取可变的参数长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试替换MATLAB/MEX并切换到Python.我遇到过SWIG,CTYPE和AMP.Cython作为可能的解决方案,并开始尝试SWIG(这似乎很简单).

I am trying to replace MATLAB/MEX and switch to Python. I came across SWIG, ctypes & Cython as possible solutions and started trying out SWIG (which seems very simple).

我的C函数具有可变的参数长度,形式为 main(int argc,char * argv []).我在网上找到了解决方案,但是与SWIG一起使用会导致很多问题.

My C functions have variable argument lengths of the form main(int argc, char *argv[]). I found solutions online, but getting this working with SWIG lead to a lot of issues.

  1. 其他方法(ctypes/Cython)更简单吗?
  2. 任何使用SWIG来完成此任务的示例都是有帮助的.

推荐答案

实际上有SWIG文档中的示例就是使用Python进行此类功能的例子.我在这里引用了一个小的更改:

There's actually an example in the SWIG documentation for exactly this sort of function with Python. I've quoted it here with a minor change:

%typemap(in) (int argc, char *argv[]) {
  int i;
  if (!PyList_Check($input)) {
    PyErr_SetString(PyExc_ValueError, "Expecting a list");
    return NULL;
  }
  $1 = PyList_Size($input);
  $2 = (char **) malloc(($1+1)*sizeof(char *));
  for (i = 0; i < $1; i++) {
    PyObject *s = PyList_GetItem($input,i);
    if (!PyString_Check(s)) {
        free($2);
        PyErr_SetString(PyExc_ValueError, "List items must be strings");
        return NULL;
    }
    $2[i] = PyString_AsString(s);
  }
  $2[i] = 0;
}

%typemap(freearg) (int argc, char *argv[]) {
   free($2); // If here is uneeded, free(NULL) is legal
}

这允许您在Py​​thon中做简单的事情:

This allows you in Python to do simply:

import test
test.foo(["a", "b", "c"])

其中 test 是您给SWIG提供的模块的名称,而 foo 是与签名 int argc,char * argv [] 匹配的函数代码>.对于Python程序员而言,使用起来简单直观,它封装并重用了复杂的位.

Where test is the name of the module you gave SWIG and foo is a function that matches the signature int argc, char *argv[]. Simple and intuitive to use for a Python programmer and it encapsulates and reuses the complex bit.

尽管文档似乎没有提到,但是已经有一个接口文件可以为您完成所有这些工作:

What the documentation doesn't seem to mention though is that there's an interface file that does all this for you already:

%module test

%include <argcargv.i>

%apply (int ARGC, char **ARGV) { (int argc, char *argv[]) }

void foo(int argc, char *argv[]);

足够了.

这篇关于Python C包装器,用于读取可变的参数长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 05:55