spe*_*tak 87 python ctypes python-3.x
我的任务是将ac包"包装"到python类中.在这个问题上,文档非常模糊.似乎他们期望只有高级python用户才能实现ctypes.好吧,我是python的初学者,需要帮助.
一步一步的帮助将是美好的.
所以我有我的c库.我该怎么办?我把哪些文件放在哪里?如何导入库?我读到可能有一种方法可以"自动换行"到Python?
(顺便说一句,我在python.net上做了ctypes教程,但它不起作用.意思是我认为他们假设我应该能够完成剩下的步骤.
实际上这是我用他们的代码得到的错误:
File "importtest.py", line 1
>>> from ctypes import *
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
我真的可以一步一步地帮助这个!谢谢〜
Chi*_*chi 203
这是一个快速而又脏的ctypes教程.
首先,编写C库.这是一个简单的Hello world示例:
#include <stdio.h>
void myprint(void);
void myprint()
{
printf("hello world\n");
}
Run Code Online (Sandbox Code Playgroud)
现在将其编译为共享库(此处找到mac修复):
$ 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
Run Code Online (Sandbox Code Playgroud)
然后,使用ctypes编写一个包装器:
import ctypes
testlib = ctypes.CDLL('/full/path/to/testlib.so')
testlib.myprint()
Run Code Online (Sandbox Code Playgroud)
现在执行它:
$ python testlibwrapper.py
Run Code Online (Sandbox Code Playgroud)
你应该看到输出
Hello world
$
Run Code Online (Sandbox Code Playgroud)
如果您已经考虑过库,则可以跳过本教程的非python部分.确保ctypes可以通过将其放入/usr/lib或另一个标准目录来查找库.如果执行此操作,则在编写包装器时无需指定完整路径.如果您选择不这样做,则必须在调用时提供库的完整路径ctypes.CDLL().
这不是一个更全面的教程的地方,但如果您在本网站上寻求特定问题的帮助,我相信社区会帮助您.
PS:我假设你使用的是Linux,因为你已经习惯了ctypes.CDLL('libc.so.6').如果你在另一个操作系统上,事情可能会有所改变(或者很多).
Ed *_*ith 42
Chinmay Kanchi的答案非常好,但我想要一个函数的例子,它传递并将变量/数组返回给C++代码.我虽然在这里包含它,以防它对其他人有用.
传递和返回一个整数
函数的C++代码,它接受一个整数并将一个加到返回值,
extern "C" int add_one(int i)
{
return i+1;
}
Run Code Online (Sandbox Code Playgroud)
保存为文件test.cpp,请注意所需的 extern"C"(这可以删除C代码).这是使用g ++编译的,其参数类似于Chinmay Kanchi的答案,
g++ -shared -o testlib.so -fPIC test.cpp
Run Code Online (Sandbox Code Playgroud)
的Python代码使用load_library从numpy.ctypeslib假设的路径,共享库在相同的目录中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)
Run Code Online (Sandbox Code Playgroud)
这按预期打印6.
传递和打印数组
您还可以按如下方式传递数组,以便C代码打印数组元素,
extern "C" void print_array(double* array, int N)
{
for (int i=0; i<N; i++)
cout << i << " " << array[i] << endl;
}
Run Code Online (Sandbox Code Playgroud)
以前编译并以相同方式导入.那么使用这个函数的额外Python代码就是,
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)
Run Code Online (Sandbox Code Playgroud)
我们指定数组的第一个参数print_array,作为指向Numpy对齐的数组的指针,c_contiguous 64位浮点数,第二个参数作为一个整数,告诉C代码Numpy数组中的元素数.然后由C代码打印如下,
1.4
2.6
3.0
Run Code Online (Sandbox Code Playgroud)
Len*_*bro 11
首先:>>>您在python示例中看到的代码是一种表明它是Python代码的方法.它用于将Python代码与输出分开.像这样:
>>> 4+5
9
Run Code Online (Sandbox Code Playgroud)
在这里,我们看到开头的行>>>是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-Extension文件.它的好处是您编写的所有Python代码都是C语言,因此您编写的对象也使用C语言,这可以提高性能.但是你必须学习它如何与C接口,所以学习如何使用它需要额外的工作.
ctypes的好处是没有C代码可以编译,因此用它来包装由其他人编写的标准库非常好,并且已经存在于Windows和OS X的二进制版本中.
| 归档时间: |
|
| 查看次数: |
81728 次 |
| 最近记录: |