2

I am interested in writing functions in C++ that can later be "imported" in Python. For example I wrote a simple function in C++ that adds two int numbers:

//function declaration
int addition(int a,int b);

//function definition
int addition(int a,int b)
{
    return (a+b);
}

I also have a header file which contains:

extern "C" MATHLIBRARY_API int addition(int a, int b);

Then in Python the code is straightforward due to the help of ctypes:

import ctypes

path = "C:\\my path to the .dll file"

# load the library
lib = ctypes.CDLL('{0}\MathLibrary.dll'.format(path))
answer = lib.addition(14, 2)
print(answer) // OUTPUT: 16

Everything works good so far, but I would like to do some math with more complex data structures such as vectors. I would like to have a vector of elements (example: {12, 10, 2, 14}) and add a number to all of the elements inside the vector. For example, n = 2, vector = {12, 10, 2, 14}, output = {14, 12, 4, 16}. I wrote a function that works in C++ but I can't manage to do the binding to Python. I believe that is due to the fact I am working with vectors and that extern "C" in the header file.

IceCode
  • 177
  • 1
  • 13
  • [ctypes](https://docs.python.org/3/library/ctypes.html) is for C code, not for C++. – jabaa Aug 20 '22 at 15:28
  • Look at pybind11, cython, boost.python, etc, they all mean to simplify interfacing C++ with python. – Marc Glisse Aug 20 '22 at 15:30
  • it seems like you are compiling a shared library for use with ctypes, which limits your interfaces to sending c types and arrays of c types and pointers, but if you compiled your code into a python extension module you can return lists or other python objects (like numpy arrays, or your own defined datadtype) that will contain your data, with the downside that your file can only be used inside python, (and you will also be limited to a certain compiler) – Ahmed AEK Aug 20 '22 at 16:24

1 Answers1

1

ctypes only allows you to interact with a library using C types, not C++. boost.python, pybind11, etc allow you pass C++ objects.

However, there is a way to do what you want to do in ctypes using C-style arrays.

Declare a function like this:

extern "C" MATHLIBRARY_API void addToArray(int *array, int num, int size);

and define it like this:

void addToArray(int *array, int num, int size)
{
    for (int i=0; i < size; ++i)
    {
        array[i] = array[i] + num;
    }
}

Then in your Python script do this:

nums = [12, 10, 2, 14]
array_type = ctypes.c_int * len(nums)
lib.additionArray.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.c_int, ctypes.c_int]
array = array_type(*nums)
lib.addToArray(array, ctypes.c_int(2), ctypes.c_int(len(nums)))
# copy modified array into original list
nums[:] = list(array)
print(nums)
jignatius
  • 6,304
  • 2
  • 15
  • 30
  • 1
    Thank you for the solution! I was not aware that ctypes is only for C. I will definitely spend some time with pybind11 and boost to understand how they work. – IceCode Aug 21 '22 at 13:32