运行 在 C++ (Cython) 中编译了带参数的 python 脚本
Run compiled python script with arguments in C++ (Cython)
我试图实现的是 将我的 Python 脚本编译为 lib/dll 并使用参数调用它.
这是我的 setup.py 脚本文件:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("nu3k2nu4k.py")
)
使用此命令生成编译输出:
python setup.py build_ext --inplace
生成了以下文件:
nu3k2nu4k.c
nu3k2nu4k.cp36-win_amd64.pyd
nu3k2nu4k.pyx
和一个名为 build 的子目录,其中包含:
nu3k2nu4k.cp36-win_amd64.exp
nu3k2nu4k.cp36-win_amd64.lib
nu3k2nu4k.obj
如何从带参数的 C++ 代码调用编译后的脚本?
我使用 Cython 完成任务,但这不是强制性的,也可以使用 boost 或其他工具(我这样做是为了使源代码不可访问)。
编辑:
使用 Mykola Shchetinin 提供的文档,我成功地为我的脚本生成了一个 API 头文件。我基本上在我的主要功能中添加了一个 cdef api 关键字。虽然这确实帮助我将方法名称导出到 C++,但我仍然需要一种方法来将一些参数传递给我的脚本。因为我传递了字符串参数,所以我希望有一种类似的方式,比如使用 PyRun 来设置 argv 并解析脚本中的参数(因为我想尽可能避免将字符串从 c 转换为 python 编码)有没有传递这些字符串参数的简单方法?
编辑 2:
我成功了!按照 Mykola 提供的示例并直接编译 c 文件输出而不是使用 .lib 我让它工作了。
我试过自己做。所以我在 cython 中将 char *
转换为 bytes
。 (根据docs)
这就是我想到的。我有以下设置(gcc 和 centos7.2):
setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("func.pyx")
)
main.c
#include "Python.h"
#include "func.h"
int main() {
Py_Initialize();
initfunc();
func("0123hello jorghy!!");
Py_Finalize();
return 0;
}
func.pyx
cdef public func(char * arg):
cdef bytes py_bytes = arg
print(str(py_bytes));
我使用以下命令构建所有这些东西:
python setup.py build_ext --inplace
gcc -I/usr/include/python2.7 -lpython2.7 -Wall -Wextra -O2 -g -o test main.c func.c
然后当运行可执行文件测试时,我得到以下结果:
0123hello jorghy!!
更新
还有另一种方法可以解决这个问题:
我创建了一个cython文件test.pyx:
import sys
if __name__ == "__main__":
print("hei")
print(sys.argv)
并使用以下命令将其编译为可执行文件:
cython test.pyx --embed
gcc -I/usr/include/python2.7 -lpython2.7 -Wall -Wextra -O2 -g -o test test.c
那么你可以将这段代码作为可执行文件来调用:
$ ./test 1 2 3
hei
['./test', '1', '2', '3']
然后您可以使用 std::system 或其他(更好的)方法从 C++ 调用它。
我试图实现的是 将我的 Python 脚本编译为 lib/dll 并使用参数调用它.
这是我的 setup.py 脚本文件:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("nu3k2nu4k.py")
)
使用此命令生成编译输出:
python setup.py build_ext --inplace
生成了以下文件:
nu3k2nu4k.c
nu3k2nu4k.cp36-win_amd64.pyd
nu3k2nu4k.pyx
和一个名为 build 的子目录,其中包含:
nu3k2nu4k.cp36-win_amd64.exp
nu3k2nu4k.cp36-win_amd64.lib
nu3k2nu4k.obj
如何从带参数的 C++ 代码调用编译后的脚本?
我使用 Cython 完成任务,但这不是强制性的,也可以使用 boost 或其他工具(我这样做是为了使源代码不可访问)。
编辑:
使用 Mykola Shchetinin 提供的文档,我成功地为我的脚本生成了一个 API 头文件。我基本上在我的主要功能中添加了一个 cdef api 关键字。虽然这确实帮助我将方法名称导出到 C++,但我仍然需要一种方法来将一些参数传递给我的脚本。因为我传递了字符串参数,所以我希望有一种类似的方式,比如使用 PyRun 来设置 argv 并解析脚本中的参数(因为我想尽可能避免将字符串从 c 转换为 python 编码)有没有传递这些字符串参数的简单方法?
编辑 2:
我成功了!按照 Mykola 提供的示例并直接编译 c 文件输出而不是使用 .lib 我让它工作了。
我试过自己做。所以我在 cython 中将 char *
转换为 bytes
。 (根据docs)
这就是我想到的。我有以下设置(gcc 和 centos7.2):
setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("func.pyx")
)
main.c
#include "Python.h"
#include "func.h"
int main() {
Py_Initialize();
initfunc();
func("0123hello jorghy!!");
Py_Finalize();
return 0;
}
func.pyx
cdef public func(char * arg):
cdef bytes py_bytes = arg
print(str(py_bytes));
我使用以下命令构建所有这些东西:
python setup.py build_ext --inplace
gcc -I/usr/include/python2.7 -lpython2.7 -Wall -Wextra -O2 -g -o test main.c func.c
然后当运行可执行文件测试时,我得到以下结果:
0123hello jorghy!!
更新
还有另一种方法可以解决这个问题:
我创建了一个cython文件test.pyx:
import sys
if __name__ == "__main__":
print("hei")
print(sys.argv)
并使用以下命令将其编译为可执行文件:
cython test.pyx --embed
gcc -I/usr/include/python2.7 -lpython2.7 -Wall -Wextra -O2 -g -o test test.c
那么你可以将这段代码作为可执行文件来调用:
$ ./test 1 2 3
hei
['./test', '1', '2', '3']
然后您可以使用 std::system 或其他(更好的)方法从 C++ 调用它。