Python 编译混合 C 和 C++ 扩展

Python Compile Mixed C and C++ Extension

我正在尝试使用 PyBind11 编译 libspng,以便我可以轻松地将图像数据转换为 numpy 数组。

编译过程需要编译几个 C 文件,然后 link将它们编译为 C++。但是,我不确定如何使用 Python setuptools 执行此操作。到目前为止,我一直在编译所有 C++ 或所有 C 模块,但在 clang 上,当我将 pybind11 文件与 C 文件混合时,这会导致问题。

有没有一种简单的方法可以让我在 setup.py 内将 C 文件编译并 link 为 C++?

我尝试为 libspng 构建一个扩展,但我不确定如何引用构建文件夹中已编译的共享对象文件。

谢谢!

如果它有用(并且因为我在拖延),我基于 spng 示例构建了一个小演示

// pywrappers.cpp
#include <pybind11/pybind11.h>
#include <utility>
#include <cstdio>
extern "C" {
    #include <spng/spng.h>
}

namespace py = pybind11;

std::pair<size_t, size_t> get_size(const std::string& filename)
{
    FILE* fp = fopen(filename.c_str(), "rb");

    if (fp == nullptr)
    {
        fclose(fp);
        throw std::runtime_error("File not found");
    }

    spng_ctx* ctx = spng_ctx_new(0);

    spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE);

    size_t limit = 1024 * 1024 * 64;
    spng_set_chunk_limits(ctx, limit, limit);

    spng_set_png_file(ctx, fp);

    struct spng_ihdr ihdr;
    spng_get_ihdr(ctx, &ihdr);

    spng_ctx_free(ctx);
    fclose(fp);

    return std::make_pair<size_t, size_t>(ihdr.width, ihdr.height);
}


PYBIND11_MODULE(foo, m)
{
    m.def("get_size", &get_size);
}
# setup.py
from setuptools import setup, Extension
import pybind11

SPNG_SOURCE = './libspng-0.7.1' # Wherever you put the spng headers and .a

libfoo = Extension(
    'foo',
    sources=['pywrappers.cpp'],
    extra_compile_args = ['-std=c++14'],
    include_dirs=[SPNG_SOURCE, pybind11.get_include()],
    extra_link_args=['-lspng_static','-lz'],
    library_dirs=[SPNG_SOURCE]
)

if __name__ == "__main__":
    setup(
        name = 'foo',
        ext_modules=[libfoo],
    )

像往常一样构建扩展,例如python setup.py build_ext --inplace。那么例如

import foo
foo.get_size('stuff.png')