将 python list 作为 'float*' 或 'int*' 传递给 C/C++
Pass python list to C/C++ as 'float*' or 'int*'
c/c
void func(float* xyz1, float* xyz2,int n){
//do something
for(int i=0; i<n;i++){
printf("%f %fn",xyz1[i],xyz2[i]);
}
}
python
import numpy as np
n = 1000000
xyz1 = np.random.random((n,)).tolist()
xyz2 = np.random.random((n,)).tolist()
#pass above array to the C/C++ code for further processing.
func(xyz1,xyz2,n) # <-- the call to the c/c++ code
我看到了使用更多高级数据结构(例如C 的array
)调用C 代码的示例。但是,我只想使用int
和float *
有任何简单的方法,例如pybind11或python的内置C类型?
您可以使用ctypes
实现此目标。首先使用C API创建共享对象。ctypes
不支持C ,而只能C。这意味着您可以在源代码中使用C ,但是您必须提供一个没有C 语言功能的C界面,例如功能过载或名称Mangling。因此,函数定义用extern "C"
标记。
然后将共享对象加载到Python中。设置参数类型和结果类型。最后,您可以调用您的功能。这是一个示例:
import ctypes
import numpy as np
n = 1000000
xyz1 = np.random.random((n,)).tolist()
xyz2 = np.random.random((n,)).tolist()
#pass above array to the C/C++ code for further processing.
Func = ctypes.CDLL("path/to/libFunc.so")
Func.func.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int]
res = Func.func(xyz1,xyz2,n) # <-- the call to the c/c++ code
我没有测试它,因此可能存在一些错误,但我认为这个想法应该很清楚。这是我测试的示例:
cmakelists.txt:
cmake_minimum_required (VERSION 3.5.1)
project (DotProduct)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_BUILD_TYPE Debug)
add_library(DotProduct SHARED src/DotProduct.cpp src/DotProduct.h)
dotproduct.h:
extern "C" double dotProduct(double* l, double* r, unsigned int len);
dotproduct.cpp:
#include "DotProduct.h"
double dotProduct(double *l, double *r, unsigned int len) {
double sum(0);
while (len--) {
sum += l[len] * r[len];
}
return sum;
}
main.py:
import ctypes
def dot_product(v1, v2):
l = len(v1)
if l != len(v2):
return 0
vec1 = (ctypes.c_double * l)(*v1)
vec2 = (ctypes.c_double * l)(*v2)
Dot_Product = ctypes.CDLL("build/lib/libDotProduct.so")
Dot_Product.dotProduct.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_uint]
Dot_Product.dotProduct.restype = ctypes.c_double
return Dot_Product.dotProduct(vec1, vec2, l)
vec1 = [2, 2]
vec2 = [2, 3]
print("{} * {} = {}".format(vec1, vec2, dot_product(vec1, vec2)))
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- 长 长 int 不要 长 int 好
- C++程序在循环后给出奇怪的int值
- 如何计算数据类型的范围,例如int
- 如果"new int"返回"int*",那么为什么"new int[n]"不返回"int**"?
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)