我的任务是将一个c库“包装”成一个python类。在这个问题上,文件含糊得令人难以置信。看起来他们希望只有高级的python用户才会实现ctype。嗯,我是python的初学者,需要帮助。
一些循序渐进的帮助将是很棒的。
所以我有我的c库。我做什么好?我应该把什么文件放在哪里?如何导入库?我读到可能有一种方法可以“自动包装”到Python?
(顺便说一句,我在python.net上做了ctype教程,但它不能工作。这意味着他们认为我应该能够完成剩下的步骤。
实际上,这就是我在他们的代码中得到的错误:
File "importtest.py", line 1
>>> from ctypes import *
SyntaxError: invalid syntax在这方面我真的需要一些循序渐进的帮助!谢谢~
发布于 2011-02-23 02:33:49
这里有一个快速而肮脏的ctype教程。
首先,编写你的C库。下面是一个简单的Hello world示例:
testlib.c
#include <stdio.h>
void myprint(void);
void myprint()
{
printf("hello world\n");
}现在将其编译为共享库(mac fix found here):
$ gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c
# or... for Mac OS X
$ gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC testlib.c然后,使用ctype编写一个包装器:
testlibwrapper.py
import ctypes
testlib = ctypes.CDLL('/full/path/to/testlib.so')
testlib.myprint()现在执行它:
$ python testlibwrapper.py您应该会看到输出
Hello world
$如果您已经有了一个库,那么可以跳过本教程中的非python部分。通过将库放在/usr/lib或其他标准目录中,确保ctype可以找到它。如果这样做,就不需要在编写包装器时指定完整路径。如果选择不执行此操作,则在调用ctypes.CDLL()时必须提供库的完整路径。
这不是一个更全面的教程的地方,但是如果你在这个网站上寻求关于特定问题的帮助,我相信社区会帮助你的。
PS:我假设您使用的是Linux,因为您使用过ctypes.CDLL('libc.so.6')。如果你使用的是另一个操作系统,情况可能会有一点变化(或者很大)。
发布于 2017-03-16 18:25:31
Chinmay Kanchi的回答很好,但我想要一个将变量/数组传递并返回给C++代码的函数的示例。我想我应该把它包含在这里,以防它对其他人有用。
传递和返回整数的
函数的C++代码接受一个整数并将返回值加1,
extern "C" int add_one(int i)
{
return i+1;
}另存为文件test.cpp,请注意required外部的"C“(对于C代码,可以将其删除)。这是用g++编译的,其参数类似于Chinmay Kanchi的答案。
g++ -shared -o testlib.so -fPIC test.cppPython代码使用numpy.ctypeslib中的load_library,假定共享库的路径与Python脚本位于同一目录中,
import numpy.ctypeslib as ctl
import ctypes
libname = 'testlib.so'
libdir = './'
lib=ctl.load_library(libname, libdir)
py_add_one = lib.add_one
py_add_one.argtypes = [ctypes.c_int]
value = 5
results = py_add_one(value)
print(results)这会像预期的那样打印6。
传递和打印数组的
您还可以按如下方式传递数组,对于打印数组元素的C代码,
extern "C" void print_array(double* array, int N)
{
for (int i=0; i<N; i++)
cout << i << " " << array[i] << endl;
}它像以前一样编译,并以相同的方式导入。使用此函数的额外Python代码将是,
import numpy as np
py_print_array = lib.print_array
py_print_array.argtypes = [ctl.ndpointer(np.float64,
flags='aligned, c_contiguous'),
ctypes.c_int]
A = np.array([1.4,2.6,3.0], dtype=np.float64)
py_print_array(A, 3)其中我们指定数组,print_array的第一个参数是指向对齐的c_contiguous 64位浮点数的Numpy数组的指针,第二个参数是整数,它告诉C代码Numpy数组中元素的数量。然后通过C代码打印,如下所示,
1.4
2.6
3.0发布于 2011-02-23 02:47:45
首先:您在python示例中看到的>>>代码是一种表明它是Python代码的方式。它用于将Python代码与输出分开。如下所示:
>>> 4+5
9在这里我们可以看到,以>>>开头的代码行是Python代码,9是它的结果。如果你启动一个Python解释器,它看起来就是这样的,这就是为什么它是这样做的。
永远不要在>>> .py 文件中输入部件。
这解决了你的语法错误。
其次,ctypes只是包装Python库的几种方法之一。其他方法是SWIG,它将查看您的Python库并生成一个公开C API的Python C扩展模块。另一种方法是使用Cython。
它们都有优点和缺点。
SWIG只会将你的C API暴露给Python。这意味着您没有获得任何对象或任何东西,您必须创建一个单独的Python文件来完成这些操作。然而,通常会有一个名为"wowza“的模块和一个名为"_wowza”的SWIG模块,它是C API的包装器。这是一种既好又简单的做事方式。
Cython生成一个C扩展文件。它的好处是,您编写的所有Python代码都是用C编写的,所以您编写的对象也是用C编写的,这可以提高性能。但是你必须学习它是如何与C语言接口的,所以学习如何使用它需要做一些额外的工作。
ctypes的好处是不需要编译C代码,所以用它来包装其他人编写的标准库非常好,并且已经存在于Windows和OS的二进制版本中。
https://stackoverflow.com/questions/5081875
复制相似问题