Листинг [SciPy.Docs]: интерфейс внешних функций C-типов (numpy.ctypeslib) (и [Python 3.Docs]: ctypes - библиотека сторонних функций для Python на всякий случай).
Это очень похоже на [SO]: вызов функции C в Python через ctypes, но функция возвращает неправильное значение (ответ @ CristiFati) (дубликат), этопросто случается также задействовать NumPy .
Другими словами, у вас есть Неопределенное поведение , так как аргументы должны быть 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" {
#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: передать и вернуть двумерный массив двойных указателей из python в c ++ (ответ @ CristiFati) (и ссылка [SO]: проблемы спередача и получение массивов для функции C с использованием ctypes (ответ @ CristiFati) ).