如何在swig类型映射中重用代码?

2024-04-29 16:52:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个swig类型图,里面有一堆重复的代码。我想把代码合并如下:

%{
   #include "structure_defs.h"
%}

%ignore Cartesian2PyList(const schrodinger::Cartesian&);
PyObject* Cartesian2PyList(const schrodinger::Cartesian& cartesian)
{
  PyObject *o;
  o = PyList_New(3);
  PyObject* item = PyFloat_FromDouble(cartesian.x);
  PyList_SetItem(o, 0, item);
  item = PyFloat_FromDouble(cartesian.y);
  PyList_SetItem(o, 1, item);
  item = PyFloat_FromDouble(cartesian.z);
  PyList_SetItem(o, 2, item);
  return o; 
}

%typemap(out) schrodinger::Cartesian
{
  $result = Cartesian2PyList($1);
}
%typemap(out) std::vector<schrodinger::Cartesian>
{
  PyObject *o;
  o = PyList_New($1.size());
  for (uint i=0; i<$1.size(); i++) {
    PyObject *elem = Cartesian2PyList($1.at(i));
    PyList_SetItem(o, i, elem);
  }
  $result = o;
}

%include "cartesian.h"

但是,这无法编译,因为在编译时找不到Cartesian2PyList的定义。在多个类型映射中重用代码的最佳方法是什么?你知道吗


Tags: 代码newincludeitempyobjectpylistconstcartesian
1条回答
网友
1楼 · 发布于 2024-04-29 16:52:08

您可以使用%{ %}将代码直接传递到生成的.c文件。因此,在包装器中重用代码的最简单方法就是将代码放在包装器中,可能是作为一个静态函数,这样它就不会与同一模块中的任何其他代码发生冲突。在您的示例中,这将起作用:

%{
   #include "structure_defs.h"
%}

%{
static PyObject* Cartesian2PyList(const schrodinger::Cartesian& cartesian)
{
  PyObject *o;
  o = PyList_New(3);
  PyObject* item = PyFloat_FromDouble(cartesian.x);
  PyList_SetItem(o, 0, item);
  item = PyFloat_FromDouble(cartesian.y);
  PyList_SetItem(o, 1, item);
  item = PyFloat_FromDouble(cartesian.z);
  PyList_SetItem(o, 2, item);
  return o; 
}
%}

%typemap(out) schrodinger::Cartesian
{
  $result = Cartesian2PyList($1);
}
%typemap(out) std::vector<schrodinger::Cartesian>
{
  PyObject *o;
  o = PyList_New($1.size());
  for (uint i=0; i<$1.size(); i++) {
    PyObject *elem = Cartesian2PyList($1.at(i));
    PyList_SetItem(o, i, elem);
  }
  $result = o;
}

%include "cartesian.h"

如果您愿意,您可以在这里将两个%{ %}块合并为一个块。你知道吗

我还删除了那里的%ignore指令,因为%{ %}中的代码只是输出到生成的模块中,而不是包装,因此是多余的。另一方面,如果您真的想在生成的代码中包装和定义它,您可以使用%inline %{ ... %},例如:

%inline %{
static PyObject* Cartesian2PyList(const schrodinger::Cartesian& cartesian)
{
    //...
}
%}

如果要编写更通用的SWIG代码,而不仅仅是一个模块,那么可以使用一些更智能的东西,请参见fragments^{}^{}。在简单的情况下,只需编写代码供模块内部使用(如上所示)就足够了。你知道吗

相关问题 更多 >