October 26, 2024
Chicago 12, Melborne City, USA
C#

Load shared object using ctyped.cdll.loadLibrary from dist-packages folder


I created this setup.py to compile a libDIV.so shared library and install it.

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']}
)

After running python3 setup.py install, the shared library is placed in the dist-packages folder as:

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

In an extra file example.py I want to load the library using ctypes.cdll.LoadLibrary, such that example.py can wrap it’s functionality in more elegant, type checked python functions.

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))]

However I’m not sure how to pass the right file name and location for the created shared object file.

How should I distribute / configure setup.py for a library of c-files which build into a shared library and some python code to wrap the c-functionality?

For completeness, this is 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;
}

EDIT:

Currently I do this to find the file name:

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)

But honestly, this is quite smelly. I’m not sure the file will always be called DIV.something.so and that vice versa that other files are not named like this.



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video