// rtc_plugins.cpp #define IMPLEMENT_NUMPY_API // 标记这是实现文件 #include "util/numpyStub.h" #include "util/RTCContext.h" // 提供转换接口 void** get_numpy_api() { return (void**)RTC_PLUGINS_ARRAY_API; } namespace py = boost::python; int init(const char* selfUserId, const char* selfDisplayName, const char* selfRoomId, boost::python::object callback) { RTCContext::instance().setPyCallback(callback); bool res = RTCContext::instance().init(selfUserId, selfDisplayName, selfRoomId); if (res) { return 0; } else { return -1; } } int initRecv(const char* destRoomId, const char* srcUserId, const int16_t destChannelIndex) { bool res = RTCContext::instance().initRecv(destRoomId, srcUserId, destChannelIndex); if (res) { return 0; } else { return -1; } } int initSend(const char* srcRoomId, const char* destRoomId, const int16_t destChannelIndex, const uint8_t channelNum) { bool res = RTCContext::instance().initSend(srcRoomId, destRoomId, destChannelIndex, channelNum); if (res) { return 0; } else { return -1; } } py::object create_int16_array() { // 1. 定义数组维度(1维,长度为 4) npy_intp dims[1] = {4}; // 2. 创建原生 C 数组(int16_t 数据) int16_t data[4] = {1, 2, -3, 4}; // 示例数据 // 3. 通过 NumPy C API 创建 PyObject* PyObject* py_array = PyArray_SimpleNewFromData( 1, // 维度数 dims, // 各维度大小 NPY_INT16, // 数据类型(np.int16) data // 数据指针 ); if (!py_array) { throw std::runtime_error("Failed to create NumPy array"); } // 4. 转换为 py::object(自动管理引用计数) return py::object(py::handle<>(py_array)); } int sendCustomAudioData(int16_t destChannelIndex, py::object pD, int32_t sampleRate, uint64_t channelNum, uint64_t dataLen) { try { // 强制转换为 int16 连续数组 PyObject* py_array = PyArray_FROM_OTF( pD.ptr(), NPY_INT16, NPY_ARRAY_IN_ARRAY | NPY_ARRAY_FORCECAST ); if (!py_array) { throw std::runtime_error("Failed to convert input to int16 array"); } // 修复点:使用花括号初始化 py::object arr{py::handle<>(py_array)}; // 检查数据长度 PyArrayObject* npArray = reinterpret_cast(arr.ptr()); if (PyArray_SIZE(npArray) != static_cast(dataLen)) { Py_DECREF(py_array); throw std::runtime_error("Array length does not match dataLen"); } // 处理数据... void* dataPtr = PyArray_DATA(npArray); int ret = RTCContext::instance().sendCustomAudioData( destChannelIndex, dataPtr, sampleRate, channelNum, dataLen ); Py_DECREF(py_array); // 释放临时数组 return ret; } catch (...) { PyErr_SetString(PyExc_RuntimeError, "Invalid audio data"); return -1; } } void init_numpy() { // 直接调用底层函数,绕过宏的问题 if (_import_array() < 0) { PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); throw std::runtime_error("NumPy initialization failed"); } std::cout << "NumPy API addr: " << PyArray_API << std::endl; } BOOST_PYTHON_MODULE(rtc_plugins) { try { init_numpy(); void** numpyApi = (void**)PyArray_API; if (!numpyApi || !numpyApi[93]) { // 93是PyArray_SimpleNew的偏移量 std::cout << "NumPy API corrupt! Key functions missing." << std::endl; PyErr_Print(); throw std::runtime_error("Invalid NumPy API state"); } else { RTCContext::instance().setNumpyApi(numpyApi); std::cout << "set numpyApi succ:" << numpyApi[93] << std::endl; } py::def("init", &init); py::def("initRecv", &initRecv); py::def("initSend", &initSend); py::def("sendCustomAudioData", &sendCustomAudioData); } catch (...) { PyErr_SetString(PyExc_RuntimeError, "Module initialization failed"); } }