清单[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 <stdint.h>#if defined(_WIN32)# define DLL00_EXPORT_API __declspec(dllexport)#else# define DLL00_EXPORT_API#endif#if defined(__cplusplus)extern "C" {#endifDLL00_EXPORT_API uint16_t dll00Func00(uint16_t **ppArr);#if defined(__cplusplus)}#endifuint16_t dll00Func00(uint16_t **ppArr) { return ppArr[5][5];}
pre00.py:
#!/usr/bin/env python3import sysimport ctypes as ctimport numpy as npDLL_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 pre 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:WorkDevStackOverflowq058727931]> sopr.bat*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***[prompt]> "c:Installx86MicrosoftVisual Studio Community2017VCAuxiliaryBuildvcvarsall.bat" x64************************************************************************ Visual Studio 2017 Developer Command prompt v15.9.17** Copyright (c) 2017 Microsoft Corporation**********************************************************************[vcvarsall.bat] Environment initialized for: 'x64'[prompt]> dir /bpre00.pydll00.c[prompt]> cl /nologo /DDLL dll00.c /link /NOLOGO /DLL /OUT:dll00.dlldll00.c Creating library dll00.lib and object dll00.exp[prompt]> dir /bpre00.pydll00.cdll00.dlldll00.expdll00.libdll00.obj[prompt]> "e:WorkDevVEnvspy_064_03.07.03_test0scriptspython.exe" pre00.pyPython 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32NumPy: 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: 5Done.
可以在[SO]中找到所有这些时髦转换的说明:C 和Python:将2D双指针数组从python传递并返回到c (@ CristiFati的回答)(以及参考的[SO]:传递和获取数组的问题使用ctypes的C函数(@CristiFati的答案))。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)