从C线程使用可变C数组调用Python函数 [英] Calling a Python function from a C thread, with a mutable C array

查看:93
本文介绍了从C线程使用可变C数组调用Python函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为一个用C ++编写的小型音频库创建Python扩展。当打开音频流时,将回调函数作为参数(当然还有其他参数)传递。一个简化的用例:

I'm in the process of creating a Python extension for a small audio library written in C++. When opening an audio stream, a callback function is passed as a parameter (among other parameters of course). A sligthly simplified use case:

AudioThingy *a = new AudioThingy();
a->openStream(..., callbackFunction);
a->startStream();

我的Python扩展程序将其包装在Python类中。

My Python extension wraps this inside a Python class.

thingy = AudioThingy()
thingy.openStream(..., pythonCallbackFunction)
thingy.startStream()

现在,该扩展具有作为C函数的回调,并将其传递给C ++库。对于每个流标记,回调都会接收有关该流的一些信息以及指向音频缓冲区的空指针,该指针将根据流格式参数将回调转换为正确的数据类型。我的意图当然是用C语言实现的回调函数调用以某种数组作为参数的用户指定的Python函数,然后将其填充例如来自以Python打开的wav文件的音频数据。

Now, the extension has a callback as a C function which it passes to the C++ library. For every stream tick the callback receives some information about the stream along with a void pointer to the audio buffer that the callback casts to the correct data type according to the stream format parameter. My intent is of course for this callback function implemented in C to call the user specified Python function with some sort of array as the argument which would then be filled with audio data from, for example, a wav-file opened with Python.

这就是我想做的代码:

static int __audiothingy_callback(void *buffer, ...) {
  PyGILState_STATE state = PyGILState_Ensure();
  /*
      cast the void pointer to the correct data type (short, int, long, etc.)
      wrap it for Python somehow
  */
  PyEval_CallObject(the_python_function, arglist);
  PyGILState_Release(state);
  //proceed to fill the buffer with stuff passed back from python
  for (...)
    *casted_buffer++ = ????
  Py_DECREF(arglist);
  return 0;
}

TL; DR:如何从中传递正确类型的可变数组C,到一个线程中,然后可以用于填充音频缓冲区的Python函数?也许可以用不同于我上面描述的方式来完成它?欢迎所有输入。

TL;DR: How do I pass a mutable array of the correct type from C, in a thread, to a Python function which can then be used to populate the audio buffer? Maybe it can be done in a different way than I have described above? All input is welcome.

推荐答案

我认为您可以做一些事情。如果您使用的是Python 2.7,则可以使用新的缓冲协议创建一个memoryview对象:

I think you could do a couple things. If you're using Python 2.7 you could create a memoryview object using the new buffer protocol:

  • New buffer protocol, Py_buffer

然后,您需要从缓冲区创建一个memoryview对象:

Then, you'd need to create a memoryview object from the buffer:

  • PyMemoryView_FromBuffer

另一种策略是导入数组模块,并使用它创建所需类型的数组。您使用:

Another strategy would be to import the array module, and use this to create an array of the desired type. You use:

  • PyImport_ImportModule
  • PyModule_GetDict
  • PyObject* array_type = PyDict_GetItemString(dict, "array");

然后,构造数组,根据所需的类型

Then, construct the array, according to the type needed:

PyObject *array = PyObject_CallFunction(array_type, "c", 'd');   

更简单的是,您可以使用字节数组对象:

Even easier, you could just use a bytearray object:

  • PyByteArray_FromStringAndSize to construct a byte array if you can structure things such that you don't need to worry about the size of array elements.

这篇关于从C线程使用可变C数组调用Python函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆