2017-11-03 18 views
0

私はPythonでctypesを使用しています。 これは構造体である:私はスフィアの構造体のためのクラスを宣言し、私はrender機能にargTypesのを設定する必要がPythonでPythonの構造体へのポインタの配列へのポインタを渡す方法

void render(Sphere** spheres); 

typedef struct { 
    float x; 
    float y; 
    float z; 
    float radius; 
} Sphere; 

そして、私は次のプロトタイプと機能を持っています

lib_render = ctypes.cdll.LoadLibrary('librender.so') 

class Sphere(ctypes.Structure): 
    _fields_ = [('x', ctypes.c_float), 
       ('y', ctypes.c_float), 
       ('z', ctypes.c_float), 
       ('radius', ctypes.c_float)] 

render = lib_render.render 
render.argtypes = [<cannot find out what needs to be here>] 

spheres = numpy.array([Sphere(1, 2.8, 3, 0.5), 
         Sphere(4.2, 2, 1, 3.2)]) 
render(spheres) 

正しく配列を渡すには?

+0

私はこれをテストしていませんが、私は、 ' – jacob

+0

が、私はそれを試してみましたが、動作しません、それは' ctypes.POINTER(ctypes.POINTER(スフィア))になると仮定したいです。 numpy配列を自動的に 'LP_LP_Sphere'に変換することはできません。また、' spheres.ctypes.data_as(POINTER(POLLER)) '関数に渡すと、関数は不明なガベージを受信します。 – Dimansel

+0

'numpy.ctypeslib.ndpointer'を調べましたか? – jacob

答えて

1

私はnumpyをあまり使っていませんが、以下はそれなしで動作します。私はあなたがポインタにポインタを渡している場合、ポインタリストがNULLで終わらなければならないと仮定しています。

from ctypes import * 

class Sphere(Structure): 
    _fields_ = [('x', c_float), 
       ('y', c_float), 
       ('z', c_float), 
       ('radius', c_float)] 

dll = CDLL('test') 
dll.render.argtypes = POINTER(POINTER(Sphere)), 
dll.render.restype = None 

# Create a couple of objects 
a = Sphere(1,2,3,4) 
b = Sphere(5,6,7,8) 

# build a list of pointers, null-terminated. 
c = (POINTER(Sphere) * 3)(pointer(a),pointer(b),None) 
dll.render(c) 

テストDLL:

#include <stdio.h> 

typedef struct Sphere { 
    float x; 
    float y; 
    float z; 
    float radius; 
} Sphere; 

__declspec(dllexport) void render(Sphere** spheres) 
{ 
    for(;*spheres;++spheres) 
     printf("%f %f %f %f\n",(*spheres)->x,(*spheres)->y,(*spheres)->z,(*spheres)->radius); 
} 

出力:numpy

1.000000 2.000000 3.000000 4.000000 
5.000000 6.000000 7.000000 8.000000 

void render(Sphere* spheres, size_t len)、この作品を使用しました。 Sphere**がサポートされている場合は、numpyに詳しい方がコメントできます。

from ctypes import * 
import numpy as np 

class Sphere(Structure): 
    _fields_ = [('x', c_float), 
       ('y', c_float), 
       ('z', c_float), 
       ('radius', c_float)] 

dll = CDLL('test') 
dll.render.argtypes = POINTER(Sphere),c_size_t 
dll.render.restype = None 

a = Sphere(1,2,3,4) 
b = Sphere(5,6,7,8) 
# c = (Sphere * 2)(a,b) 
# dll.render(c,len(c)) 
d = np.array([a,b]) 
dll.render(d.ctypes.data_as(POINTER(Sphere)),len(d)) 
+0

ニースのアプローチ。ポインタを数値で掛けてポインタの配列を得ることはできません。私は数え切れないほどの配列を必要としないと思う。 – Dimansel

関連する問題