C语言如何把数组传给PYTHON,如何将2d数组从Python传递到C?

博客介绍了如何在Python中使用ctypes库正确地调用C函数,特别是处理二维数组的情况。通过示例代码展示了如何定义C函数、创建Python接口以及传递和接收二维数组。博客还提供了详细的错误分析和解决方案,强调了argtypes参数必须为CTypes类型而非NumPy类型。
摘要由CSDN通过智能技术生成

小编典典

清单[SciPy.Docs]:C-Types外部函数接口(numpy.ctypeslib)(和[Python 3.Docs]:ctypes-Python的外部函数库,以防万一。

这就像[SO]一样:通过ctypes在Python中调用C函数,但是函数返回的值不正确(@CristiFati的回答)(重复),它碰巧也涉及NumPy。

换句话说,您具有Undefined Behavior,因为argtypes必须是CTypes类型(不是 NumPy)。

下面是您的代码的修改后的版本,可以正常工作。

dll00.c:

#include

#if defined(_WIN32)

# define DLL00_EXPORT_API __declspec(dllexport)

#else

# define DLL00_EXPORT_API

#endif

#if defined(__cplusplus)

extern "C" {

#endif

DLL00_EXPORT_API uint16_t dll00Func00(uint16_t **ppArr);

#if defined(__cplusplus)

}

#endif

uint16_t dll00Func00(uint16_t **ppArr) {

return ppArr[5][5];

}

code00.py:

#!/usr/bin/env python3

import sys

import ctypes as ct

import numpy as np

DLL_NAME = "./dll00.dll"

def main():

UI16Ptr = ct.POINTER(ct.c_uint16)

UI16PtrPtr = ct.POINTER(UI16Ptr)

dll00 = ct.CDLL(DLL_NAME)

dll00Func00 = dll00.dll00Func00

dll00Func00.argtypes = [UI16PtrPtr]

dll00Func00.restype = ct.c_uint16

dim0 = 10

dim1 = 10

np_arr_2d = np.empty([dim0, dim1], dtype=np.uint16)

np_arr_2d[5][5] = 5

print(np_arr_2d)

# The "magic" happens in the following (3) lines of code

ct_arr = np.ctypeslib.as_ctypes(np_arr_2d)

UI16PtrArr = UI16Ptr * ct_arr._length_

ct_ptr = ct.cast(UI16PtrArr(*(ct.cast(row, UI16Ptr) for row in ct_arr)), UI16PtrPtr)

res = dll00Func00(ct_ptr)

print("\n{0:s} returned: {1:d}".format(dll00Func00.__name__, res))

if __name__ == "__main__":

print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))

print("NumPy: {0:s}\n".format(np.version.version))

main()

print("\nDone.")

输出:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q058727931]> sopr.bat

*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***

[prompt]> "c:\Install\x86\Microsoft\Visual Studio Community\2017\VC\Auxiliary\Build\vcvarsall.bat" x64

**********************************************************************

** Visual Studio 2017 Developer Command Prompt v15.9.17

** Copyright (c) 2017 Microsoft Corporation

**********************************************************************

[vcvarsall.bat] Environment initialized for: 'x64'

[prompt]> dir /b

code00.py

dll00.c

[prompt]> cl /nologo /DDLL dll00.c /link /NOLOGO /DLL /OUT:dll00.dll

dll00.c

Creating library dll00.lib and object dll00.exp

[prompt]> dir /b

code00.py

dll00.c

dll00.dll

dll00.exp

dll00.lib

dll00.obj

[prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py

Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32

NumPy: 1.16.2

[[19760 5277 632 0 32464 5280 632 0 111 114]

[ 107 92 68 101 118 92 86 69 110 118]

[ 115 92 112 121 95 48 54 52 95 48]

[ 51 46 48 55 46 48 51 95 116 101]

[ 115 116 48 92 108 105 98 92 115 105]

[ 116 101 45 112 97 5 107 97 103 101]

[ 115 92 110 117 109 112 121 92 116 101]

[ 115 116 105 110 103 92 95 112 114 105]

[ 118 97 116 101 92 110 111 115 101 116]

[ 101 115 116 101 114 46 112 121 0 0]]

dll00Func00 returned: 5

Done.

可以在[SO]中找到所有这些时髦转换的说明:C 和Python:将2D双指针数组从python传递并返回到c(@ CristiFati的回答)(以及参考的[SO]:传递和获取数组的问题使用ctypes的C函数(@CristiFati的答案))。

2020-12-20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值