Загрузите общий объект с помощью ctyped.cdll.loadLibrary из папки dist-packages

Я создал этот setup.py для компиляции общей библиотеки libDIV.so и ее установки.

from distutils.core import setup, Extension

libDIV = Extension(
  'DIV',
  sources = ['example.c']
)

setup (
  name = 'divv',
  version = '0.1',
  description = 'DIVV, you want it',
  ext_modules = [libDIV],
  packages = [''],
  package_data={'': ['libDIV.so']}
)

После запуска python3 setup.py install общая библиотека помещается в папку dist-packages как:

/usr/local/lib/python3.4/dist-packages/DIV.cpython-34m.so

В дополнительном файле example.py я хочу загрузить библиотеку, используя ctypes.cdll.LoadLibrary, чтобы example.py мог обернуть ее функциональность в более элегантные функции Python с проверкой типов.

import ctypes
lib = ctypes.cdll.LoadLibrary('DIV.so') # not sure what to do here

def divide_modulo(a, b):
  div = ctypes.c_int(0)
  rest = ctypes.c_int(0)
  lib.divide_modulo(a, b, ctypes.byref(div), ctypes.byref(rest))
  return (div.value, rest.value)

print(divide_modulo(11, 4))

class DynamicArray(ctypes.Structure):
  _fields_ = [("n", ctypes.c_int), ("r", ctypes.POINTER(ctypes.c_int))]

Однако я не уверен, как передать правильное имя файла и местоположение для созданного общего объектного файла.

Как мне распространять/настраивать setup.py для библиотеки c-файлов, которые встраиваются в общую библиотеку, и некоторый код Python для переноса c-функциональности?

Для полноты это example.c:

#include <stdlib.h>

void divide_modulo(int a, int b, int *div, int *rest)
{
*div  = a / b;
*rest = a % b;
}

typedef struct dynamic_array {
  int n;
  int *r;
} dynamic_array;

dynamic_array return_dynamic_array(int n)
{
  dynamic_array r;
  r.n = n;
  r.r = (int *)malloc(sizeof(int) * n);
  unsigned int i = 0;
  for (; i < n; ++i)
  r.r[i] = i;
  return r;
}

ИЗМЕНИТЬ:

В настоящее время я делаю это, чтобы найти имя файла:

import ctypes, numpy, site, os.path
from scipy.sparse import csr_matrix

so_file = next(
    os.path.join(directory, filename)
    for directory in site.getsitepackages()
    for filename in os.listdir(directory)
    if filename.startswith("DIV.") and filename.endswith(".so")
)
lib = ctypes.cdll.LoadLibrary(so_file)

Но, честно говоря, это довольно вонючий. Я не уверен, что файл всегда будет называться DIV.something.so и наоборот, что другие файлы не будут называться так.


person Herbert    schedule 21.12.2015    source источник
comment
Вы нашли лучшее решение? Я только что опубликовал аналогичную проблему (stackoverflow.com/questions/61434262).   -  person Friedrich    schedule 26.04.2020
comment
Я даже смутно не помню, что я здесь делал, но я так не думаю, извините.   -  person Herbert    schedule 26.04.2020