将一组指针投射到其他对象?

Posted

技术标签:

【中文标题】将一组指针投射到其他对象?【英文标题】:Cast an array of pointers to other objects? 【发布时间】:2013-02-21 10:06:01 【问题描述】:

我正在尝试将一组对象发送到我的 c 库。

我要发送的对象是一个 pymunk Body。它有一个嵌入其中的指针对象Body._body。我能够将一个单一的传递给我的函数,并使用 Chipmunk 函数提取我想要的任何东西。我将cpBodyGetMass 用作测试并且有效。

如果我将这些组成一个数组。唯一有效的是第一个。

我希望能够将Body._body 地址作为数组发送到我的 dll。我想我可以将指针存储在 c_intc_long 数组中,并将这些地址转换为 Chipmunk 想要的 cpBody

这是我的自定义函数

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 字节整数的数组。 cpBody body[] 假定它必须跳转,以数组中的 sizeof(cpBody) 字节为单位,才能到达下一个对象。但他们不是内联的。它是指向所有主体的随机指针列表。我需要它来读取每个数组元素中的地址,并让它假设该位置有一个cpBody

如果你看第二个例子。我通过单个指针发送了一个数组。我需要发送一个指向指针数组的指针并从每个指针中获取 cpBody。这意味着我需要数组只跳转 4 个字节并将内存地址读取为cpBody

【问题讨论】:

【参考方案1】:

这是一个简短的示例,说明将一组 pymunk.Body 对象发送到 c lib 的一种方式:

首先是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 路径中)

【讨论】:

非常感谢!我想不通的两个原因。我不知道 c++ 中的 ** ,也不知道你可以制作这样的指针数组。耶。一个问题。 sys.path.insert(0,'..') 是做什么的 这是为了让我的代码找到pymunk。我的标准 python 中没有安装 pymunk。因此, path.insert 将路径插入到我的本地 pymunk 文件夹。在我的情况下,这只是一个文件夹(我在 pymunk 源代码树内的转储文件夹中有此代码),但它可能是任何东西.. 例如,在我的情况下,绝对路径是 sys.path.insert(0, '''c:\svn\pymunk\trunk''')【参考方案2】:

我不确定,但你使用 cpBodyGetAngle(body) 不应该是 cpBodyGetAngle(bd)cpBodyGetPos 也是如此),因为这总是会将数组衰减为指向第一个元素的指针。

如果这不是您想要的,您能描述一下什么不起作用吗?你的程序是否崩溃,产生意想不到的结果,...

【讨论】:

唯一可行的方法是我只发送一个。我没有 python 数组来存储这些指针,以便 cpp 读取它们。只有第一个元素会起作用。没有崩溃可能是因为我只是在阅读。它的阅读记忆很可能是空白的或完全是其他东西。 @Kaliber64:If I make an array of these. The only one that works is the first one.。我无法理解,您是否尝试过将数组/列表从 python 传递给 c?也许你应该展示你想从 python 传递给 c 的代码(最小的例子)。无论如何,请务必查看这个问题,也许它会有所帮助:***.com/questions/2307290/… 我没有考虑结构,但我会着手处理更多信息。

以上是关于将一组指针投射到其他对象?的主要内容,如果未能解决你的问题,请参考以下文章

用于游戏开发和其他目的的光线投射教程

用于游戏开发和其他目的的光线投射教程

用于游戏开发和其他目的的光线投射教程

将一组类对象添加到一个主类对象中

使用 Weka 将一组特征作为一个来衡量

尝试将一组对象保存到 Firestore 并将其加载回来