Ошибка при создании привязки Python - PullRequest
1 голос
/ 23 марта 2012

Эта программа на 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 ]

2 голосов
/ 23 марта 2012

Вам необходимо указать флаги компоновщика (-lfoo) после ваших исходных файлов. Это связано с тем, как работает компоновщик: когда вы указываете ему библиотеку, он проверяет библиотеку на наличие символов, необходимых до сих пор. Если символы не нужны (как если бы вы еще не дошли ни до каких исходных объектов), он просто пропускает библиотеку.

Попробуйте следующую командную строку:

gcc -shared -I/usr/include/python2.7 \
     `pkg-config --cflags libatasmart` \
     atabind.c \
     `pkg-config --libs libatasmart` \
     -o pySmart.so -fPIC
1 голос
/ 31 июля 2013

Сначала вы должны включить свой Python.h, затем любой заголовок std.

Все определения функций, типов и макросов, необходимые для использования API Python / C, включены в ваш код

#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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...