小编Jos*_*iah的帖子

Cython - 将指向数组的指针转换为Python对象

好吧,我非常接近完成这个我可以品尝它.在过去几周左右的时间里,我一直在尝试创建一个Python扩展,以便通过Cython与用C++编写的库进行交互.在这里和一些朋友的帮助下,我已经设法获得了98%的感觉.唯一剩下的就是这个:我不能为我的生活找出如何将指向无符号短裤数组的指针变成python对象(最好是列表).

一点背景,我试图与设置回调函数的库的一部分接口,我已经成功完成了这个:

global callbackfunc

ctypedef unsigned short const_ushort "const uint16_t"

ctypedef void (*Function1)(const_ushort *data, unsigned width, unsigned height)

cdef extern from "lib.hpp":
    void SetCallback(Function1)

cdef void cSetCallback(Function1 function):
    SetCallback(function)

cdef void callcallback(const_ushort *data, unsigned width, unsigned height):
    global callbackfunc
    callbackfunc(data,width,height)

cSetCallback(callcallback)

def PySetCallback(callbackFunc):
    global callbackfunc
    callbackfunc = callbackFunc
Run Code Online (Sandbox Code Playgroud)

问题出现在函数"callcallback"中,我得到错误:"无法将'const_ushort*'转换为Python对象".我第一次尝试这个是创建一个新的python列表,并循环以将数组的每个元素放入python列表,如下所示:

datalist = []
for i in range(width*height):
    datalist += data[i]
Run Code Online (Sandbox Code Playgroud)

遗憾的是,在编译的cython代码中,我试图将类型定义为"const const unsigned short",这显然是一个问题.

然后我尝试了这个:

datalist = []
for i in data:
    datalist += i
Run Code Online (Sandbox Code Playgroud)

这让我"C数组迭代需要已知的结束索引".请注意,我对C/C++知之甚少,所以大部分内容对我来说都没有多大意义.

所以,无论如何,是否有任何有效的方法将这样的指针转换为python对象(最好比循环遍历数组更快,因为它通常约为57344项,这对时间非常敏感)

编辑:稍微澄清一下,正如我所提到的,我正在使用回调,并且调用它的库中的C++函数会发送一个指向"const uint_16"数组的指针,这就是我用这种方式定义const_ushort的原因,因为否则类型不统一.我无法以任何方式修改库.

Edit2 …

python cython

10
推荐指数
1
解决办法
4047
查看次数

Cython - 实现回调

我一直在使用Cython尝试与用c ++编写的库进行交互.到目前为止,事情进展顺利,我可以有效地使用库中的MOST函数.我唯一的问题在于实现回调.该库有4个函数定义,看起来像这样:

typedef void (*Function1)(const uint16_t *data, 
                         unsigned width, unsigned height);
void SetCallBack(Function1);
Run Code Online (Sandbox Code Playgroud)

所以为了实现它们,我想我会用cython做这样的事情:

ctypedef void (*Function1)(unsigned short *data, 
                         unsigned width, unsigned height);
cdef extern from "lib.hpp":
    void SetCallBack(Function1)
Run Code Online (Sandbox Code Playgroud)

然而,实际上编译正确,我不能为我的生活思考如何以回调可行的方式实际实现它.我首先尝试创建一个只调用它的函数,类似于你为任何其他函数执行它的方式,得出这个:

def PySetCallBack(Func):
    SetCallBack(Func)
Run Code Online (Sandbox Code Playgroud)

但这给了我(可预测的)错误:

"无法将Python对象转换为'Function1'"

所以,是的,那就是我在的地方.如果有人有任何在Cython中设置回调的经验,我将非常感谢任何帮助.谢谢.

编辑:根据您的建议,我创建了一个带有cdef的中间函数,如下所示:

cdef void cSetCallBack(Function1 function):
    SetCallBack(function)
Run Code Online (Sandbox Code Playgroud)

这似乎让我...更近了?至少现在得到一个不同的错误:

error: invalid conversion from ‘void (*)(short unsigned int*, unsigned int, unsigned int)’ to ‘void (*)(const uint16_t*, unsigned int, unsigned int)’
Run Code Online (Sandbox Code Playgroud)

现在,我可以说这些类型是相同的,所以我无法弄清楚发生了什么.

Edit2:通过声明一个新的typedef修复了这个问题:

ctypedef unsigned short uint16_t
Run Code Online (Sandbox Code Playgroud)

并使用它作为调用的参数,但显然实际上并没有更接近,但只是带我绕过一个侧轨,因为当试图调用该函数时,我得到相同的"无法将Python对象转换为'Function1' "再次出错.

所以,我几乎回到了我开始的地方.我现在唯一可以做的就是明确地将python对象作为交流函数进行投射,但是,说实话,我不知道如何去做.

编辑第三个:好吧,在解析你的答案之后我终于得到了它,它有效,所以万岁等等.我最终做的是创建这样的函数:

cdef void cSetCallback(Function1 function): …
Run Code Online (Sandbox Code Playgroud)

c++ python cython

8
推荐指数
2
解决办法
4060
查看次数

使用PyOpenGL渲染带纹理的矩形

我正在使用PyOpenGL开发一个项目,我正在尝试让OpenGL呈现一种启动画面.我决定的解决方案是绘制纹理2D矩形.不幸的是,似乎无论我做什么,都没有画出任何东西,我只是得到一个黑色的屏幕(所以我想有些东西被绘制,否则它将是一个透明的窗口,但它绝对不是我想要的).这是我班级的相关代码:

class ClassThing:
    def __init__(self):
        self.Splash = True
        glutInit(sys.argv)

    def TexFromPNG(self, filename):
        img = Image.open(filename)
        img_data = numpy.array(list(img.getdata()), numpy.uint8)

        texture = glGenTextures(1)
        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
        glBindTexture(GL_TEXTURE_2D, texture)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
        return texture

    def run(self):
        glutInitDisplayMode(GLUT_RGBA)

        glutInitWindowSize(256,224)
        self.window = glutCreateWindow("GL")
        glutDisplayFunc(self.draw)

        glClearColor(0,0,0,0)
        glEnable(GL_TEXTURE_2D)
        glEnable(GL_VERTEX_ARRAY)

        self.MainTex = glGenTextures(1)
        self.SplashTex = self.TexFromPNG("Resources/Splash.png")

        glutMainLoop()

    def draw(self):
        glClear(GL_COLOR_BUFFER_BIT)
        glLoadIdentity()
        if self.Splash:
            glBindTexture(GL_TEXTURE_2D, self.SplashTex)
        else:
            glBindTexture(GL_TEXTURE_2D, self.MainTex)

        glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) …
Run Code Online (Sandbox Code Playgroud)

python opengl glut

6
推荐指数
1
解决办法
8464
查看次数

PyOpenGL:渲染......嗯......真的

我一直在研究一个使用Python和OpenGL的项目.我之前发布了类似的问题,但我已经做了一些研究并转而使用了不推荐的函数.按照本教程(显然将其翻译成Python版本),我最终得到了这段代码:

import sys
import OpenGL

from OpenGL.GL import *
from OpenGL.GL.shaders import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from OpenGL.GLUT.freeglut import *
from OpenGL.arrays import vbo
import pygame
import Image
import numpy    

class AClass:
    def __init__(self):
        self.Splash = True    #There's actually more here, but it's impertinent
    def TexFromPNG(self, filename):
        img = Image.open(filename) # .jpg, .bmp, etc. also work
        img_data = numpy.array(list(img.getdata()), 'B')
        texture = glGenTextures(1)
        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
        glBindTexture(GL_TEXTURE_2D, texture)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
        glTexParameterf(GL_TEXTURE_2D, …
Run Code Online (Sandbox Code Playgroud)

python opengl pyopengl

2
推荐指数
1
解决办法
3900
查看次数

标签 统计

python ×4

cython ×2

opengl ×2

c++ ×1

glut ×1

pyopengl ×1