首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pybind11和全局C变量

Pybind11和全局C变量
EN

Stack Overflow用户
提问于 2018-02-09 23:08:30
回答 1查看 1.4K关注 0票数 1

我无法使用pybind11将全局变量从C语言导出到Python。这个问题可以从一个简单的例子中重现。假设我们有一个头文件(global.h),如下所示:

代码语言:javascript
运行
复制
#ifndef GLOBAL_H
#define GLOBAL_H

extern int array[];

#endif 

该数组在C文件(global.c)中定义,如下所示:

代码语言:javascript
运行
复制
#include "global.h"

int array[] = {1, 2, 3, 4};

我想使用pybind11和下面的C++文件(pyglobal.cpp)在Python模块中导出这个数组:

代码语言:javascript
运行
复制
#include <pybind11/pybind11.h>

extern "C"
{
  #include "global.h"
}

PYBIND11_MODULE(pyglobal, m)
{
  m.attr("array") = array;
}

当我用CMake (CMakeLists.txt)生成库时,一切正常:

代码语言:javascript
运行
复制
cmake_minimum_required(VERSION 2.8.12)
project(pyglobal)

find_package(pybind11 PATHS ${PYBIND11_DIR} REQUIRED)

pybind11_add_module(pyglobal pyglobal.cpp global.c)

但是当我启动一个python3外壳程序并输入

代码语言:javascript
运行
复制
import pyglobal

我得到以下错误消息:

代码语言:javascript
运行
复制
> Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyglobal
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: AttributeError: array

我在这里做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2019-11-18 07:04:16

该赋值是一个相当不幸的隐式类型转换,因此不会像您认为的那样执行。下面是公开该数组的一种方式,假设您已经安装了numpy:

代码语言:javascript
运行
复制
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>

extern "C"
{
  #include "global.h"
}

PYBIND11_MODULE(pyglobal, m)
{
  auto dtype = pybind11::dtype(pybind11::format_descriptor<int>::format());
  m.attr("array") = pybind11::array(dtype, {3}, {sizeof(int)}, array, nullptr);
}

如果您不知道大小,可以使用一个空的基数组和一个大的(假的)大小。只要确保不以范围受限的方式迭代数组即可。示例:

代码语言:javascript
运行
复制
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>

extern "C"
{
  #include "global.h"
}

PYBIND11_MODULE(pyglobal, m)
{
  auto dtype = pybind11::dtype(pybind11::format_descriptor<int>::format());
  auto base = pybind11::array(dtype, {(unsigned)-1}, {sizeof(uintptr_t)});
  m.attr("array") = pybind11::array(dtype, {(unsigned)-1}, {sizeof(int)}, array, base);
}

它可以像这样使用:

代码语言:javascript
运行
复制
>>> import pyglobal
>>> for i in range(3):
...     print(pyglobal.array[i])
... 
1
3
0
>>>

但是它例如不能被打印,因为这将在整个(unsigned)-1大小上迭代。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48708717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档