首页 > 解决方案 > Cython 从 C++ 修改指针

问题描述

我需要修改我从 cython 传递给 c++ 函数的 NumPy 数组。一切正常,但是当我在调用 c++ 修饰符函数后打印出该值时,该值与调用该函数之前的值保持不变。我也对字符串进行了同样的尝试,但也没有成功。我使用键入的内存视图来访问内存。以下是我使用的代码(仅保留与此问题相关的相关内容)

测试.h

#include <iostream>

struct S1 {
    float* buffer;
    int length;
};

int modify(S1* s1, char* str);

测试.cpp

#include "test_modify.h"

int modify(S1* s1, char* str) {
    str = "newstr"; // string modify

    int out_idx = 0;


    while(out_idx < s1->length) {
        s1->buffer[out_idx++] = 10; // array modify
    }

    return 0;
}

测试.pyx

from numpy import pi, cos, sin, arccos, arange
import numpy as np
cimport numpy as np

np.import_array()
cdef extern from "test_modify.h":

    cdef struct S1:
        float* buffer
        int length

    int modify(S1* s1, char* str)

def modifyPY():
    d = np.zeros((2, 3, 3), dtype=np.float32)
    cdef float[:, :, ::1] d_view = d.astype(np.float32)
    cdef S1 s1 = [&(d_view[0, 0, 0]), np.product(d.shape)]

    cdef char *s = 'jhk'

    modify(&s1, s)

    return d, s

** setup.py **

from setuptools import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import numpy


extensions = [
    Extension("temp",
              sources=["test.pyx", "test_modify.cpp"],
              include_dirs=[numpy.get_include()],
              extra_compile_args=["-O3", '-std=c++11'],
              language="c++")
]

setup(
    ext_modules=cythonize(extensions)
)

# to install run, python setup.py build_ext --inplace

test.py(构建后运行)

import temp

d, s = temp.modifyPY()

print(d) # still 0's, should be 10's
print(s) # still "jhk" should be "newstr'

标签: pythonc++numpypointerscython

解决方案


cdef float[:, :, ::1] d_view = d.astype(np.float32)

文档

默认情况下,astype总是返回一个新分配的数组

ied_view是副本的d视图,而不是 的视图d。因此,我们预计不会d_viewd.


int modify(S1* s1, char* str) {
    str = "newstr"; // string modify

这是一个基本的 C 指针传递问题。str并且s在 Python 中都指向同一个地方,但它们是不同的指针。在str重新分配之后,str = "newstr"它们现在指向不同的地方。

您可能想要一个指向指针的指针 ( char**)?


推荐阅读