Компиляция и взаимодействие с C DLL в Python работает на Unix, но не на Windows.Как правильно это сделать? - PullRequest
0 голосов
/ 01 февраля 2019

Итак, у меня есть следующий файл:

addone.c

long int addone(long int x){
     return x+1;
}

, который затем компилируется в DLL через установку Windows GCC 7.2.0 (я такжепопытался использовать компилятор Intel C ++, после изменения функции на extern "C" long int addone(long int x), но это не меняет результат, когда я пытаюсь загрузить его в Python):

gcc -c addone.c
gcc -shared -o addone.dll addone.o

который я затем пытаюсь загрузить вpython 3.6.7:

import ctypes
_addone = ctypes.CDLL("addone.dll")

Хотя мне удается получить объект CDLL, в нем отсутствует функция "addone".Я пытался использовать ctypes.WinDLL() и ctypes.windll.LoadLibrary методы импорта DLL-файлов C, но все они достигают одного и того же конечного результата: я получаю объект из ctypes, который не имеет открытых методов и ни одного из закрытых методов (в Pythonобъект, а не DLL), похоже, связан с функцией addone.

Просто чтобы еще раз проверить, что мой компилятор делает то, что я ожидаю, я разобрал результирующую DLL, которая выглядит как типичная DLL.Внутри функция даже не изменена по имени:

0000000530ce1030 <add_one>:
530ce1030:   55                      push   %rbp
530ce1031:   48 89 e5                mov    %rsp,%rbp
530ce1034:   48 89 4d 10             mov    %rcx,0x10(%rbp)
530ce1038:   48 8b 45 10             mov    0x10(%rbp),%rax
530ce103c:   48 83 c0 01             add    $0x1,%rax
530ce1040:   5d                      pop    %rbp
530ce1041:   c3                      retq
530ce1042:   90                      nop
<Everything between these two instructions is just more no-ops>
530ce104f:   90                      nop

Я смог выполнить эту работу в системе Unix, и у меня нет проблем с сопряжением C DLL с Python на этой платформе.Однако при переходе на Windows я чувствую, что что-то упустил.Даже пытаясь все это на другом компьютере, я все еще не могу получить доступ к функции, которую я написал.

Я чувствую, что здесь что-то упущено.Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

После некоторых недоразумений я выяснил, что происходит.

Функция действительно была написана правильно, правильно скомпилирована в DLL и правильно создан объект ctypes.CDLL.

Объект ctypes.CDLL не сразу «увидел» имя функции, поэтому его нет в списке методов.Что я сделал, так это проигнорировал тот факт, что метод не был в пространстве имен объекта, я взял прыжок веры и назвал _addone.addone(x).Это заставило объект понять, что функция находится в DLL, и она добавлена ​​в пространство имен.

Я подозреваю, что в ctypes есть некоторый back-end, где вызов функции заставляет ее проверить, является ли этоимя на самом деле существует в библиотеке.Возможно, это сделано для того, чтобы предотвратить загромождение пространства имен различными другими функциями, которые компилятор помещает в DLL.

0 голосов
/ 01 февраля 2019

Попробуйте экспортировать функцию:

#include "addone.h"

EXPORT long int addone(long int x){
    return x+1;
}

и создать заголовочный файл addone.h:

#define EXPORT __declspec(dllexport)

EXPORT long int addone(long int x);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...