9

通常のPythonで作成されたfloat値の配列があり、基になるC関数の前にあるcython関数に渡します。C関数では、次のように配列をフローティングポインタとして渡す必要があります。

void setOverlays(const float * verts);

Cythonラッパーは次のようになります。

def set_overlays(verts):
    setOverlays(verts)

vertsをcython配列にするにはどうすればよいですか?私はこれがうまくいくかもしれないと思った:

cdef float * cVerts = [v for v in verts]

ただし、残念ながら、生成される値はPythonオブジェクトであり、この場合、自動変換は機能しません。

ctypesで(機能する)同等の式は次のとおりです。

cVerts = (c_float * len(verts))()
for i in range(len(verts)):
    cVerts[i] = verts[i]
setOverlays(cast(byteref(cVerts), POINTER(c_float)))

私は同じことを達成しようとしていますが、cythonで

前もって感謝します!

4

5 に答える 5

5

これは、floatのpythonリストを繰り返し処理し、C配列に配置することで実行できると思います。

cimport cython
from libc.stdlib cimport malloc, free

cdef:
    float * cfloats
    int i

cfloats = <float *> malloc(len(pyfloats)*cython.sizeof(float))
if cfloats is NULL:
  raise MemoryError()
for i in xrange(len(pyfloats)):
  cfloats[i] = pyfloats[i]
setOverlays(cfloats)
free(cfloats)
于 2012-07-27T14:41:30.887 に答える
4

float *受け入れられた答えは間違っており、のメモリが割り当てられないため、セグメンテーション違反につながります。

@JABの答えは進むべき道を示していますが、もっと詳しく説明したいと思います。

配列を渡す:

問題は、Python配列をCスタイルの配列に変換する方法です。Python arrayarrayモジュールから)は連続メモリのラッパーであるため、メモリをコピーする必要はありません。ポインタをc関数に渡すだけです。

from cpython cimport array
import array

def set_overlays(array.array verts):
    setOverlays(verts.data.as_floats)

モジュールを使用する方が、標準ライブラリの一部であるためarrayよりも優れてnumpyいます。何かをインストールする必要はありません。この解決策は短くて素晴らしいですが、問題があります。誰かがそれをで使用する可能性がint-arrayあり、エラーは発生しません。メモリが再解釈されるだけです。時々それは人が望むものですが、ほとんどの場合これはそうではありません。

渡された配列オブジェクトが正しいタイプのデータを持っていることを確認するために、メモリビューを使用できます。

from cpython cimport array #still needed

def set_overlays_memview(float[::1] verts):
    setOverlays(&verts[0])

[::1] 、メモリビューが連続メモリをラップアラウンドすることを保証します。ただし、out-of-bounds-accessが原因で、メモリビューに要素がない場合、このコードには問題がありますverts[0]。それを処理する正しい方法は関数に依存し、setOverlaysこの答えの一部ではありません。

リストを渡す:

Pythonリストをc-functionに渡す必要がある場合は、値を連続メモリにコピーする必要があります。次の機能を使用して行うのが最適arrayです。車輪の再発明を行う必要はありません。

from cpython cimport array
import array

def set_overlays_list(list verts):
    cdef array.array a =  array.array('f', verts)
    setOverlays(a.data.as_floats) #we already know they are floats
于 2017-02-06T21:42:40.513 に答える
3

http://docs.cython.org/src/userguide/memoryviews.htmlを確認してください。また、Pythonの組み込みarrayモジュールを利用する方法やのヒントも提供しているようnumpyです。

于 2012-07-27T14:41:02.273 に答える
-1

これは、Cython、またはSWIGを使用したC/CPPに渡すための配列を準備するために使用するものです。

import numpy as np    
def make_c_array(a):
    """
    Take an input numpy array and convert to being ready for use in C.
    """
    b = []
    for i in range(len(a)):
        b.append(a[i])
    a = np.array(b,dtype=np.dtype('d'),order='C')
    return a
于 2016-09-14T08:38:49.227 に答える
-2

Cython固有の方法を見つけました:

cdef float* cVerts = []
    for i in xrange(len(verts)):
        cVerts[i] = verts[i]
setOverlays(cVerts)

興味深いことに、上記の2つのソリューションはcythonコンパイラによって拒否されました。

于 2012-08-06T02:24:15.200 に答える