创建python绑定时出错

时间:2012-03-23 17:57:14

标签: python c gcc binding shared

C中的这个程序运行并编译得很好:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>

#include <atasmart.h>
int main(){
const char *device = "/dev/sda";
int ret;
 uint64_t ms;
 SkDisk *d;
         if ((ret = sk_disk_open(device, &d)) < 0) {
                        printf("Failed to open disk\n");
                        return 1;
                }





                              if ((ret = sk_disk_smart_read_data(d)) < 0) {
                                printf("Failed to read SMART data: \n");

                        }

                        if ((ret = sk_disk_smart_get_power_on(d, &ms)) < 0) {
                                printf("Failed to get power on time:\n");

                        }

                        printf("%llu\n", (unsigned long long) ms);


            return 0;

}

使用:

gcc atatest.c `pkg-config --cflags --libs libatasmart` 

然而,在尝试基于该程序创建python绑定时:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>

#include <atasmart.h>

#include <Python.h>

 static PyObject *pySmart_powerOn(PyObject *self, PyObject *args)
{
    const char *device = "/dev/sda";
int ret;
 uint64_t ms;
 SkDisk *d;

    if (!PyArg_ParseTuple(args, "s", &device))
    {
        return NULL;
    }

                        if ((ret = sk_disk_smart_get_power_on(d, &ms)) < 0) {
                              return Py_BuildValue("s", "Failed to get power on time");

                        }
            return Py_BuildValue("K", (unsigned long long) ms);
}

static PyMethodDef pySmart_methods[] = {
        { "powerOn", (PyCFunction)pySmart_powerOn, METH_VARARGS, NULL },
        { NULL, NULL, 0, NULL }
};

PyMODINIT_FUNC initpySmart()
{
        Py_InitModule3("pySmart", pySmart_methods, "Trial module");
}

我使用

创建一个共享库
gcc -shared -I/usr/include/python2.7 `pkg-config --cflags --libs libatasmart` atabind.c -o pySmart.so -fPIC

然后我收到如下警告:,但文件编译

In file included from /usr/include/python2.7/Python.h:8:0,
                 from atabind.c:12:
/usr/include/python2.7/pyconfig.h:1158:0: warning: "_POSIX_C_SOURCE" redefined [enabled by default]
/usr/include/features.h:214:0: note: this is the location of the previous definition

在Python中我运行

import pySmart

我得到了

ImportError: ./pySmart.so: undefined symbol: sk_disk_smart_get_power_on

我的猜测是错误是因为我用不正确的标志/选项编译了pySmart.so共享库..但我无法弄明白!

2 个答案:

答案 0 :(得分:2)

您需要在源文件后指定链接器标志(-lfoo。这是因为链接器的工作方式:当你为它指定一个库时,它会检查库到目前为止所需的符号。如果不需要符号(就好像你还没有获得任何源对象),它只是跳过库。

尝试以下命令行:

gcc -shared -I/usr/include/python2.7 \
     `pkg-config --cflags libatasmart` \
     atabind.c \
     `pkg-config --libs libatasmart` \
     -o pySmart.so -fPIC

答案 1 :(得分:1)

首先应该包含Python.h,然后是任何std头。

使用Python / C API所需的所有函数,类型和宏定义都包含在您的代码中

#include "Python.h"

这意味着包含以下标准标题:  <stdio.h>, <string.h>, <errno.h>, <limits.h>, <assert.h> and <stdlib.h>(如果有)。

由于Python可能会定义一些影响某些系统上标准头的预处理器定义,因此在包含任何标准头之前必须包含Python.h。

<强>可替换地: 只是_GNU_SOURCE,它将被GNU libc的/usr/include/features.h忽略