我有一个C++程序,它有一些插件结构:当程序启动时,它在插件文件夹中查找带有某些导出函数签名的dll,例如:
void InitPlugin(FuncTable* funcTable);
Run Code Online (Sandbox Code Playgroud)
然后程序将调用dll中的函数来初始化并将函数指针传递给dll.从那时起,dll可以与程序通信.
我知道Cython允许你在Python中调用C函数,但我不确定我是否可以编写一个Cython代码并将其编译为dll,这样我的C++程序就可以用它进行初始化.一个示例代码会很棒.
是否可以构建具有某些cdef功能的 cython 模块并将生成的共享库链接到 C++ 程序中?
我尝试了一个概念证明:
cymod.pyx:
# distutils: language=c++
from libcpp.string cimport string
cdef public string simple_echo(string test_string):
return test_string
Run Code Online (Sandbox Code Playgroud)
cpp_test.cpp:
#define PyMODINIT_FUNC void
#include <iostream>
#include "cymod.h"
int main(int argc, char const *argv[])
{
std::cout << simple_echo("test") << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
设置.py:
from setuptools import setup, Extension
from Cython.Build import cythonize
setup(
name='cymod',
ext_modules=cythonize(
Extension(
"cymod", ["cymod.pyx"],
),
)
)
Run Code Online (Sandbox Code Playgroud)
cython 模块构建得很好,但是当我尝试构建将使用 cython 函数的 C++ 代码时,我得到:
$ g++ -L. -l:cymod.so cpp_test.cpp -o cpp_test
/tmp/cc48Vc2z.o: In …Run Code Online (Sandbox Code Playgroud) 我有一个与这篇文章非常相似的问题;但是,在实施建议的修复后 - 我仍然收到以下错误。
我正在尝试编译由 Cython 生成的 C 文件。
cython ConnectFour.pyx --embed
Run Code Online (Sandbox Code Playgroud)
我尝试像这样编译我的 c 文件:
gcc -I /usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/Headers -o ConnectFour ConnectFour.c
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
Undefined symbols for architecture x86_64:
"_PyBaseObject_Type", referenced from:
___Pyx_InBases in ConnectFour-3c26d7.o
"_PyBytes_FromStringAndSize", referenced from:
___pyx_pymod_exec_ConnectFour in ConnectFour-3c26d7.o
___Pyx_InitStrings in ConnectFour-3c26d7.o
"_PyCFunction_NewEx", referenced from:
___pyx_pymod_exec_ConnectFour in ConnectFour-3c26d7.o
"_PyCFunction_Type", referenced from:
___Pyx_PyObject_CallOneArg in ConnectFour-3c26d7.o
___Pyx_PyObject_CallNoArg in ConnectFour-3c26d7.o
___Pyx_PyObject_Call2Args in ConnectFour-3c26d7.o
___Pyx_PyCFunction_FastCall in ConnectFour-3c26d7.o
___pyx_pf_11ConnectFour_36eval_heuristic_score in ConnectFour-3c26d7.o
___pyx_pf_11ConnectFour_38list_valid_col_idxs in ConnectFour-3c26d7.o
___pyx_pf_11ConnectFour_40deep_copy_board in ConnectFour-3c26d7.o
...
"_PyCode_New", referenced from:
___Pyx_InitCachedConstants in ConnectFour-3c26d7.o …Run Code Online (Sandbox Code Playgroud) 我正在尝试在C程序中调用cython(cdef)函数。当cdef函数包含python语句(例如print(0.5)或python(def)函数)时,调用(cdef)函数会引发分段错误。
.pyx文件:
# cython: language_level=3
cdef public double PI = 3.1415926
cdef public double get_e():
print("calling get_e()")
return 2.718281828
Run Code Online (Sandbox Code Playgroud)
.c文件:
#include "Python.h"
#include "transcendentals.h"
#include <math.h>
#include <stdio.h>
int main(int argc, char **argv) {
Py_Initialize();
PyInit_transcendentals();
printf("pi**e: %f\n", pow(PI, get_e()));
Py_Finalize();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译命令:
cython transcendentals.pyx
gcc -I. -I/usr/include/python3.5m -I/usr/include/python3.5m \
-Wno-unused-result -Wsign-compare \
-g -fstack-protector-strong -Wformat \
-Werror=format-security -DNDEBUG -g \
-fwrapv -O3 -Wall -Wstrict-prototypes \
-L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu \
-L/usr/lib transcendentals.c main.c \
-lpython3.5m -lpthread -ldl -lutil -lm -Xlinker …Run Code Online (Sandbox Code Playgroud) 假设我正在“cythonizing”这个test.py:
import json
print(json.dumps({'key': 'hello world'}))
Run Code Online (Sandbox Code Playgroud)
和:
cython test.py --embed
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
cl test.c /I C:\Python37\include /link C:\Python37\libs\python37.lib
Run Code Online (Sandbox Code Playgroud)
正如分发嵌入 Cython 编译的代码并使其在任何机器上工作所需的最小文件集中提到的,有必要沿着文件分发python37.dll和vcruntime140.dll的内容Lib\(作为Lib\或打包到 a 中python37.zip)test.exe。
问题:如何修改cl.exe ...命令来要求编译器静态链接python37.dll到文件vcruntime140.dll内部test.exe?
(这样就不再需要运输python37.dll和单独)vcruntime140.dll
cython ×5
python ×3
c ×2
c++ ×2
dll ×2
cl ×1
cythonize ×1
plugins ×1
python-3.x ×1
visual-c++ ×1