简体   繁体   English

在Mac 10.8 64位上,使用SWIG和distutils包装包括Python API在内的C代码失败

[英]Wrapping C code including Python API using SWIG and distutils fails on Mac 10.8 64bits

I have been trying to wrap an existing C code into a Python module for some time now and I keep running into recurrent errors and a failed build... After an extensive look at the available documentation and posts on this forum I would like to know if someone has an idea why it is not working. 我一直在尝试将现有的C代码包装到Python模块中一段时间​​,并且不断遇到反复出现的错误和构建失败的情况。在仔细阅读了本论坛上的可用文档和帖子后,我想知道如果有人知道为什么它不起作用。

I would like to use the stsci.imagemanip.interp2d.expand2d() function which consists of a python script calling a C function which uses the Python.h library. 我想使用stsci.imagemanip.interp2d.expand2d()函数,该函数包含一个调用C函数的python脚本,该C函数使用Python.h库。 This under Mac 10.8 64bits with Python 2.7. 在Mac 10.8 64位和Python 2.7下。

I am new to wrapping C functions to Python and I decided to use SWIG and distutils. 我是将C函数包装到Python的新手,因此决定使用SWIG和distutils。

My input files are the following: 我的输入文件如下:

bilinearinterp.i bilinearinterp.i

/* bilinearinterp.i */
%module bilinearinterp

%{
#define SWIG_FILE_WITH_INIT
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <stdio.h>
#include <Python.h>
#include <math.h>
#include <numpy/arrayobject.h>
#include "bilinearinterp.h"
%}

static PyObject * bilinearinterp(PyObject *obj, PyObject *args);

bilinearinterp.c bilinearinterp.c

/* File: bilinearinterp.c */
#include <Python.h>
#include <stdio.h>
#include <math.h>
#include <numpy/arrayobject.h>
#include "bilinearinterp.h"

static void InterpInfo (float ai, int npts, int *i, float *p, float *q) {

/* arguments:
float ai        i: independent variable in same units as i
int npts        i: size of array within which *i is an index
int *i          o: array index close to ai
float *p, *q    o: weights for linear interpolation
*/

DO SOME CALCULATIONS 
}

int unbin2d (float *a, float *b, int inx, int iny, int onx, int ony) {

/* arguments:
PyArrayObject *a        i: input data
PyArrayObject *b        o: output data
*/

DO SOME CALCULATIONS 
CALL InterpInfo
return (1);
}

static PyObject * bilinearinterp(PyObject *obj, PyObject *args)
{
    PyObject *input, *output;
    PyArrayObject *dataa, *datab;
    int inx, iny, onx, ony;

    int status=0;

    if (!PyArg_ParseTuple(args,"OO:bilinearinterp",&input,&output))
        return NULL;

    dataa = (PyArrayObject *)PyArray_ContiguousFromAny(input, PyArray_FLOAT, 1, 2);
    datab = (PyArrayObject *)PyArray_ContiguousFromAny(output, PyArray_FLOAT, 1, 2);

    inx = PyArray_DIM(input,0);
    iny = PyArray_DIM(input,1);
    onx = PyArray_DIM(output,0);
    ony = PyArray_DIM(output,1);

    status = unbin2d((float *)dataa->data,(float *)datab->data, inx, iny, onx, ony);

    Py_XDECREF(dataa);
    Py_XDECREF(datab);

    return Py_BuildValue("i",status);
}

static PyMethodDef bilinearinterp_methods[] =
{
    {"bilinearinterp",  bilinearinterp, METH_VARARGS, 
        "bilinearinterp(input, output)"},
    {0,            0}                             /* sentinel */
};

void initbilinearinterp(void) {
    Py_InitModule("bilinearinterp", bilinearinterp_methods);
    import_array();
}

bilinearinterp.h bilinearinterp.h

/* File: bilinearinterp.H */
static PyObject * bilinearinterp(PyObject *obj, PyObject *args);

setup.py setup.py

#!/usr/bin/env python

from distutils.core import setup, Extension

bilinearinterp_module = Extension('_bilinearinterp',
                                  sources = ['bilinearinterp_wrap.c','bilinearinterp.c'],
# Path to locate numpy/arrayobject.h     
                                  include_dirs=['/Library/Python/2.7/site-packages/numpy-override/numpy/core/include'])

setup (name = 'bilinearinterp',
       version = '1.1',
       author      = "Space Telescope Science Institute - stsci_python",
       description = """bilinear interpretation for 2D array extrapolation""",
       ext_modules = [bilinearinterp_module],
       py_modules = ["bilinearinterp"],
       )

Then I run the following in Terminal: 然后在终端中运行以下命令:

>>>swig -python bilinearinterp.i
>>>python setup.py build_ext --inplace

The appropriate files are being created: _bilinearinterp.so bilinearinterp.py bilinearinterp.pyc bilinearinterp_wrap.c As well as a build directory containing some files in it. 正在创建适当的文件:_bilinearinterp.so bilinearinterp.py bilinearinterp.pyc bilinearinterp_wrap.c以及其中包含一些文件的构建目录。

I get warnings when setup.py is running but it seems to complete. 我在运行setup.py时收到警告,但似乎已完成。 Over the various tests I did two recurrent errors keep coming back: 在各种测试中,我反复出现了两个反复出现的错误:

  1. warning: "Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-W#warnings] 警告:“使用已弃用的NumPy API,通过#定义NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION来禁用它” [-W#warnings]

    Which may induces several other warnings associated to numpy 这可能会引发与numpy相关的其他一些警告

  2. warning: function 'bilinearinterp' has internal linkage but is not defined [-Wundefined-internal] static PyObject * bilinearinterp(PyObject *obj, PyObject *args); 警告:函数'bilinearinterp'具有内部链接,但未定义[-Wundefined-internal]静态PyObject * bilinearinterp(PyObject * obj,PyObject * args); bilinearinterp_wrap.c:2971:24: note: used here result = (PyObject *)bilinearinterp(arg1,arg2); bilinearinterp_wrap.c:2971:24:注意:此处使用结果=(PyObject *)bilinearinterp(arg1,arg2);

Then when calling the module in a python script I get the following: 然后,当在python脚本中调用模块时,我得到以下信息:

>>> from bilinearinterp import bilinearinterp as lininterp
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bilinearinterp.py", line 28, in <module>
    _bilinearinterp = swig_import_helper()
  File "bilinearinterp.py", line 24, in swig_import_helper
    _mod = imp.load_module('_bilinearinterp', fp, pathname, description)
ImportError: dlopen(./_bilinearinterp.so, 2): Symbol not found: _bilinearinterp
  Referenced from: ./_bilinearinterp.so
  Expected in: flat namespace
 in ./_bilinearinterp.so

Would someone have an idea from where the error could be coming from? 会有人知道错误可能来自何处吗?

Is it from my usage of SWIG or from setup.py? 是我使用SWIG还是setup.py?


Another approach with only a swig interface file and the C code (without including the *.h file) does not work. 仅带有Swig接口文件和C代码(不包括* .h文件)的另一种方法不起作用。 Based on the swig introduction chapter 基于swig介绍章节

bilinearinterp.i bilinearinterp.i

/* bilinearinterp.i */
%module bilinearinterp

%{
static PyObject * bilinearinterp(PyObject *obj, PyObject *args);
%}

static PyObject * bilinearinterp(PyObject *obj, PyObject *args);

And I compile using: 我使用以下命令进行编译:

>>>swig -python -o bilinearinterp_wrap.c bilinearinterp.i
>>>gcc -c -fpic bilinearinterp.c bilinearinterp_wrap.c
-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
-I/System//Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/core/include
bilinearinterp_wrap.c:2955:19: warning: function 'bilinearinterp' has internal
      linkage but is not defined [-Wundefined-internal]
static PyObject * bilinearinterp(PyObject *obj, PyObject *args);
                  ^
bilinearinterp_wrap.c:2971:24: note: used here
  result = (PyObject *)bilinearinterp(arg1,arg2);
                       ^
1 warning generated.
>>>gcc -bundle -flat_namespace -undefined suppress bilinearinterp.o bilinearinterp_wrap.o -o _bilinearinterp.so

Then I still get the same import error in the python interpreter. 然后我仍然在python解释器中得到相同的导入错误。 Could it be due to my numpy installation or my gcc arguments? 可能是由于numpy安装或gcc参数引起的吗?

Thanks 谢谢

Well, I don't quite understand what you are trying to achieve, but I see some bad practices. 好吧,我不太了解您要达到的目标,但是我看到了一些不良做法。 For example, you make bilinearinterp everywhere static, and static functions are not exported and only can be used in the same module where implemented. 例如,您使bilinearinterp到处都是静态的,并且静态函数不会导出,只能在实现的同一模块中使用。 I think it would be helpful to read a bit about SWIG design ideas. 我认为阅读一下SWIG设计思想会有所帮助。 For sure it will take a some time, but you will get a broader perspective of what SWIG is and isn't capable of. 当然,这将需要一些时间,但是您将获得SWIG功能的更广阔视野。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM