python c api with multiple file

335 views Asked by At

While writing python c api, I wanted to separate it into multiple files.
So, I separated the files (module.cpp and support.cpp) and wrote the function declarations in the separate files (support.h).

But how to write setup.py?

├── cpp
│   ├── module.cpp
│   ├── support.cpp
│   └── support.h
├── setup.py
└── tsmodule
    └── __init__.py

module.cpp

#include <Python.h>
#include <string.h>
#include "support.h"
// int bar(int x){
//     return x + 1;
// }

PyObject* foo(PyObject *, PyObject* args) {
    int x;
    PyArg_ParseTuple(args, "i", &x);
    char str[100];
    sprintf(str, "%d\n", bar(x));
    return PyBytes_FromStringAndSize(str, strlen(str));
}

static PyMethodDef methods[] = {
    { "foo", (PyCFunction)foo, METH_O, nullptr },
    { nullptr, nullptr, 0, nullptr }
};
static PyModuleDef module = {PyModuleDef_HEAD_INIT, "module", " ", 0, methods};
PyMODINIT_FUNC PyInit_module() {return PyModule_Create(&module);}

support.cpp

#include "support.h"
int bar(int x){return x + 1;}

support.h

#ifndef SUPPORT_H
#define SUPPORT_H
int bar(int);
#endif

tsmodule/__init__.py

from .module import foo

setup.py

from setuptools import find_packages, setup, Command, Extension
NAME = 'tsmodule'
ext_modules = [Extension('tsmodule.module', sources = ['cpp/module.cpp'])]
setup(
    name=NAME,
    ext_modules=ext_modules,
    packages=find_packages(exclude=["tests", "*.tests", "*.tests.*", "tests.*"]),
    include_package_data=True,
)

testing code (expected output: b'133\n')

import tsmodule
print(tsmodule.foo((132,)))

it return

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/mine/.local/lib/python3.9/site-packages/tsmodule/__init__.py", line 1, in <module>
    from .module import foo
ImportError: /home/mine/.local/lib/python3.9/site-packages/tsmodule/module.cpython-39-x86_64-linux-gnu.so: undefined symbol: _Z3bari
0

There are 0 answers