1

I am currently trying to use Python 3.6's ctypes module to call functions from a library written in C++.

Suppose I used ctypes to create a shared library object called myLibrary:

# Python code
myLibrary = ctypes.CDLL(mylib.dylib)

The library I'm trying to make calls from uses C++ classes, and it is impossible with ctypes to make Python calls of the form myLibrary.class()->method() (see here).

I am therefore first writing some intermediate C++ code which "wraps" the C++ class methods in a non-class form. For example, suppose Math is one of the classes, and Add() is one of its methods. My intermediate wrapper would look like this:

// C++ intermediate code
int Add(int num1, int num2){                // no reference to a class
    return Math()->Add(num1, num2);         // reference to a class
}

I then plan on compiling this C++ into a shared library (a dylib file) on which I can make calls in Python using ctypes. For example:

# Python code
def add(num1, num2):
    myLibrary.add(num1, num2)

That's the plan.

Unfortunately, many methods in the library have exotic argument and value types. Some are simply variant type names created with the typedef keyword, but others are exotic structs. Further, there is a bit of enumeration in the original C++ code.

My question is: How does one deal with custom argument and value types (and enumeration) when using ctypes?

Looking at the ctypes documentation, I know that you must specify restypes and argtypes for the methods you're trying to call, but how to do this when the original C++ functions involve exotic types and structs?

I thought the ctypes documentation might shed light on this, in section 15.17.1.6. ("Calling functions with your own custom data types"), but it just talks about the reverse scenario where you want to pass your own object types into the C++ functions.


Similar questions that were helpful, but not totally:

DyingIsFun
  • 1,227
  • 2
  • 10
  • 21

1 Answers1

2

Note that the ctypes is designed to call C code, not C++.

Since you're already writing wrappers, you only need to change one thing - specify that these wrapper functions have C linkage:

// C++ intermediate code
extern "C" int Add(int num1, int num2) {    // no reference to a class
    return Math()->Add(num1, num2);         // reference to a class
}

As for the structures and so on, you should define a proper C language interface for those. It will not be that difficult to come up with the ctypes wrapper for that.