1

オブジェクトの配列を C ライブラリに送信しようとしています。

送信しようとしているオブジェクトは pymunk Body です。ポインター オブジェクトが埋め込まれていBody._bodyます。関数に 1 つを渡すだけで、必要なものをすべて Chipmunk 関数で抽出することができました。cpBodyGetMassテストとして使用しましたが、うまくいきました。

これらの配列を作成する場合。機能するのは最初のものだけです。

Body._bodyアドレスを配列として dllに送信できるようにしたいと考えています。ポインターをc_intorc_long配列に格納し、それらのアドレスをcpBodyChipmunk が必要とする に変換できると考えました。

これが私のカスタム関数です

int pymunk_body(int color_id, int numof, float * values, cpBody * body){

    glBindTexture(GL_TEXTURE_2D,0);
    cpBody bd;
    float red;
    float green;
    float blue;
    float alpha;
    float sizex;
    float sizey;
    cpVect position;
    float positionx;
    float positiony;
    float rotation;

    for (int i=0;i<numof*6;i=i+6){
        bd=body[i/6];
        red=values[0+i];
        green=values[1+i];
        blue=values[2+i];
        alpha=values[3+i];
        sizex=values[4+i];
        sizey=values[5+i];
        position=cpBodyGetPos(body);
        positionx=position.x;
        positiony=position.y;
        rotation=cpBodyGetAngle(body)*180/PI;
    }

私の C++ には Python ラッピングがないため、C オブジェクトしか送信できません。私がこれまで行ってきた方法は...

    gldll[4](ctypes.c_int(add_color),
    ctypes.c_float(color[0]),
    ctypes.c_float(color[1]),
    ctypes.c_float(color[2]),
    ctypes.c_float(color[3]),
    ctypes.c_float(position[0]),
    ctypes.c_float(position[1]),
    ctypes.c_float(rotation),
    ctypes.c_float(size[0]),
    ctypes.c_float(size[1]))

    ni=numpy.array([self.texture.TextureID,ublur,add_color,blurSize,self.Blur+blur,textfont],"i")
    nf=numpy.array([(self.width+self.height)/2.0,color[0],color[1],color[2],color[3],position[0],position[1],rotation,self.half_width,self.half_height,scale],"f")

    gldll[2](ctypes.c_void_p(ni.ctypes.data),ctypes.c_void_p(nf.ctypes.data))

ここで、ポインターの配列を送信するとします。基本的には 4 バイトの int の配列です。はcpBody body[]、次のオブジェクトに到達するには、配列内の sizeof(cpBody) のバイト単位でジャンプする必要があると想定しています。しかし、それらはインラインではありません。すべてのボディへのランダムなポインターのリストです。各配列要素のアドレスを読み取り、その場所に があると仮定する必要がありcpBodyます。

2番目の例を見ると。単一のポインターを介して配列を送信しました。ポインターの配列にポインターを送信し、それぞれから cpBody を取得する必要があります。つまり、配列が 4 バイトだけジャンプし、メモリ アドレスをcpBody.

4

2 に答える 2

1

これは、pymunk.Body オブジェクトの配列を ac lib に送信する 1 つの方法の短い例です。

最初のCコード:

#include "chipmunk.h"

double mass_sum(size_t numof, cpBody ** body);
double mass_sum(size_t numof, cpBody ** body){
    double total = 0;  
    for (int i=0; i<numof; i++){    
         total += cpBodyGetMass(body[i]);
    }
    return total;
}

次に、python コード:

from ctypes import *
import sys
sys.path.insert(0,'..')

import pymunk 

sendbody_lib = windll.LoadLibrary("sendbody.dll")

cpBody = pymunk._chipmunk.cpBody

mass_sum = sendbody_lib.mass_sum
mass_sum.restype = c_double
mass_sum.argtypes = [c_int, POINTER(POINTER(cpBody))]

b1 = pymunk.Body(1, 1)
b2 = pymunk.Body(10, 1)
bodies = [b1._body, b2._body, b1._body]
arr = (POINTER(cpBody) * len(bodies))(*bodies)

print mass_sum(len(arr), arr)  

(最初に見られるように、コードがpymunkを見つけるようにパスを変更する必要がありましたが、それはデフォルトでpythonパスにインストールされていないためです)

于 2013-03-04T22:11:29.520 に答える
0

よくわかりませんが、使用するcpBodyGetAngle(body)べきではありませんcpBodyGetAngle(bd)(同じcpBodyGetPos)。これは、配列が常に最初の要素へのポインターに減衰するためです。

これがあなたが探しているものではない場合、何が機能していないのか説明していただけますか? プログラムがクラッシュしたり、予期しない結果が発生したりしませんか? ...

于 2013-02-21T12:08:02.763 に答える