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共享库..但我无法弄明白!
答案 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忽略