Pybind11:外部类型作为返回值

Posted

技术标签:

【中文标题】Pybind11:外部类型作为返回值【英文标题】:Pybind11: external type as return value 【发布时间】:2019-11-06 11:53:01 【问题描述】:

使用 pybind11,我需要绑定一个函数,该函数返回一个对象类型,该对象类型的绑定已经可以从另一个扩展模块(也使用 pybind11 创建)获得。我知道这通常是可能的,因为the docs say so 并且我还设法建立了complete toy example where things work fine。但是,由于某种我不明白的原因,如果外部类型是来自https://github.com/deephealthproject/pyeddl 的Tensor 类型,我无法使其工作。我知道-fvisibility=hidden 不是问题,因为:

它也出现在玩具示例中; 我也尝试过在没有它的情况下重建 pyeddl。

src/dummy_bindings.cpp:

#include <pybind11/pybind11.h>
#include <eddl/tensor/tensor.h>

Tensor* mkTensor() 
    return new Tensor();


PYBIND11_MODULE(_foo, m) 
    m.def("mkTensor", &mkTensor);

setup.py:

from distutils.core import setup, Extension
import pybind11

ext = Extension(
    "_foo",
    sources=["src/dummy_bindings.cpp"],
    include_dirs=[
        "src",
        pybind11.get_include(),
        pybind11.get_include(user=True)
    ],
    libraries=["eddl"],
)

setup(
    name="foo",
    ext_modules=[ext]
)

测试python代码:

import pyeddl._core
import _foo

print(pyeddl._core.Tensor)
t = _foo.mkTensor()

这导致:

<class 'pyeddl._core.Tensor'>
Traceback (most recent call last):
  File "foo.py", line 5, in <module>
    t = _foo.mkTensor()
TypeError: Unable to convert function return value to a Python type! The signature was
    () -> Tensor

我的理解是import pyeddl._core 应该使Tensor 类型在运行时可见,并使对mkTensor 的调用起作用。至少,它在玩具示例中确实有效。但是,我收到上述错误。我也是 pyeddl 绑定的作者,所以我想知道我是否在那里做错了什么,从而阻止了其他扩展找到该类型。或者也许还有更多关于 pybind11 决定一个值是否可以转换为我不理解的 Python 类型的方式。

【问题讨论】:

【参考方案1】:

它不起作用的原因是这两个扩展是用不同版本的 gcc 编译的。

【讨论】:

以上是关于Pybind11:外部类型作为返回值的主要内容,如果未能解决你的问题,请参考以下文章

使用 pybind11 将抽象类作为参数作为参数传递

接口作为返回类型(转载)

使用pybind11开发python扩展库

向下转换为 pybind11 派生类

Pybind - 使用指向派生类的共享指针调用函数

Scala 自定义集合返回 null 列表作为默认值