【发布时间】:2022-01-17 15:22:17
【问题描述】:
我目前正在尝试使用 .so 文件在 c 中编写插件后端。在 c 中这样做可以按我的预期工作。但是我考虑为我的后端编写 python 插件。这是我偶然发现似乎很有前途的 cython 的时候。 我的后端正在调用 .so 文件中的一个函数,并期望返回一个值。
这个函数目前看起来像这样:
cdef public size_t transform_data(char *plugin_arguments, char **buffer):
printf("Entered function\n")
print("test\n")
printf("Test passed\n")
return 5
有趣的是,printf 工作得很好。但是打印没有。我怀疑这是因为我缺少的 python 模块存在某种链接错误?稍后我希望能够将任何 python 模块添加到该文件中,例如 influxdb 模块。对 influxdb.InfluxDBClient 的调用现在也不起作用,我猜与打印不起作用的原因相同。
我正在使用
编译文件cythonize -3b some_plugin.pyx
我还尝试使用如下所示的安装文件进行编译:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("some_plugin.pyx"))
我一打打印电话,两者都会导致段错误。
这是我用来调用 .so 文件的代码:
#include "execute_plugin.h"
#include <Python.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
size_t execute_plugin(char file_name[FILE_NAME_SIZE], char *plugin_arguments,
char **output_buffer) {
if (!Py_IsInitialized()) {
Py_SetPythonHome(L"/home/flo/.local/lib/python3.8");
Py_SetPath(L"/usr/lib/python3.8");
Py_Initialize();
}
if (!Py_IsInitialized())
return 0;
void *plugin;
size_t (*func_transform_data)(char *plugin_arguments, char **output_buffer);
char path[PATH_SIZE];
if (!get_path_to_file(path, PATH_SIZE)) {
printf("Could not receive the correct path to the plugin %s\n", file_name);
return 0;
}
plugin = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
if (!plugin) {
fprintf(stderr, "Error: %s\n", dlerror());
fprintf(stderr, "Cannot load %s\n", file_name);
return 0;
}
func_transform_data =
(size_t(*)(char *plugin_arguments, char **output_buffer))dlsym(
plugin, "transform_data");
if (!func_transform_data) {
fprintf(stderr, "Error: %s\n", dlerror());
dlclose(plugin);
return 0;
}
size_t length = func_transform_data(plugin_arguments, output_buffer);
printf("Size of answer is %ld\n", length);
dlclose(plugin);
Py_Finalize();
return length;
}
我已尝试使用文档并复制了示例:https://cython.readthedocs.io/en/latest/src/tutorial/embedding.html 在此示例中,我没有使用 .so 文件,而是使用 .c 和 .h 文件,这也是由 cythonize 命令生成的。有趣的是,打印功能正在工作,但是当我尝试添加另一个模块(如 influxdb 模块)并尝试从中调用一个函数时,我也会收到错误。
由于我没有找到很多关于在 c 中使用 cython 代码的信息,我想知道我正在尝试做的事情是否可能,或者是否有更好的方法。
【问题讨论】:
标签: c segmentation-fault cython .so cythonize