从 Python (ctypes) 指向 C 以保存函数输出的指针

Posted

技术标签:

【中文标题】从 Python (ctypes) 指向 C 以保存函数输出的指针【英文标题】:Pointer from Python (ctypes) to C to save function output 【发布时间】:2019-02-18 19:07:18 【问题描述】:

我是 Python 中 C 集成的新手。我目前正在使用 ctypes 将 .dll 库包装到我的 Python 代码中,并且在传递指针以保存特定函数的输出时遇到问题。

我的 C 函数具有以下结构:

函数 (int* w, int* h, unsigned short* data_output)

其中 hw 是输入,data_output 是大小为 (w x h, 1) 的数组。

通过创建 zeros(w x h,1) 数组并使用 libpointer('uint16Ptr',零(w x h,1))

如何在 Python 中做到这一点?

对于输出为 int* 类型的其他函数,我能够使用 create_string_buffer 成功检索值。但我还没有设法使它适用于这个。

谢谢。

【问题讨论】:

如果wh 是输入,为什么它们被声明为int * @MarkTolonen:从我目前了解到的情况来看,因为输入是指向变量wh 的指针,它们属于int 类型。 您不需要指向输入变量的指针。 function(int w, int h, unsigned short* data_output) 会更容易使用。由于这个原因,下面的答案没有使用它们。 【参考方案1】:

根据[SO]: How to create a Minimal, Complete, and Verifiable example (mcve),您的问题不包含基本信息(例如您的尝试)。确保在下一个更正。

另外,[Python.Docs]: ctypes - A foreign function library for Python。

这是一个说明这个概念的虚拟示例。

dll00.c

#if defined(_WIN32)
#  define DLL_EXPORT __declspec(dllexport)
#else
#  define DLL_EXPORT
#endif


DLL_EXPORT int function(int w, int h, unsigned short *pData) 
    int k = 1;
    for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++, k++)
            pData[i * w + j] = k;
    return w * h;

code00.py

#!/usr/bin/env python3

import sys
import ctypes as ct


DLL = "./dll00.so"


def print_array(data, h, w):
    for i in range(h):
        for j in range(w):
            print(":2d".format(data[i * w + j]), end=" ")
    print()


def main(*argv):
    dll_dll = ct.CDLL(DLL)
    function = dll_dll.function
    function.argtypes = [ct.c_int, ct.c_int, ct.POINTER(ct.c_ushort)]
    function.restype = ct.c_int

    h = 3
    w = 5

    ArrayType = ct.c_ushort * (h * w)  # Dynamically declare the array type: `unsigned short[15]` in our case
    array = ArrayType()  # The array type instance

    print_array(array, h, w)
    res = function(w, h, ct.cast(array, ct.POINTER(ct.c_ushort)))
    print(": returned: :d".format(function.__name__, res))

    print_array(array, h, w)


if __name__ == "__main__":
    print("Python :s :03dbit on :s\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

输出

[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/***/q054753828]> ~/sopr.sh
### Set shorter prompt to better fit when pasted in *** (or other) pages ###
[064bit prompt]> ls
code00.py  dll00.c
[064bit prompt]> gcc -fPIC -shared -o dll00.so dll00.c
[064bit prompt]> ls
code00.py  dll00.c  dll00.so
[064bit prompt]> python3 code00.py
Python 3.6.4 (default, Jan  7 2018, 15:53:53) [GCC 6.4.0] 064bit on cygwin

 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
function returned: 15
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15

Done.

【讨论】:

亲爱的克里斯蒂。感谢您对问题制定和响应的建议。我能够使用您的虚拟示例成功实现该库。最好的问候! 很高兴听到这个消息!请通过将答案标记为您的问题的解决方案来让其他人知道。

以上是关于从 Python (ctypes) 指向 C 以保存函数输出的指针的主要内容,如果未能解决你的问题,请参考以下文章

使用 ctypes 传递结构指针

Python ctypes 中的指针和数组

如何使用 ctypes 将数组从 C++ 函数返回到 Python

通过 ctypes 从 Python 调用的 C 函数返回不正确的值

无法确定从 SWIG(不是 ctypes)C 传递给 python 例程的正确参数

没有为指向结构的指针调用 ctypes.Structure 子类的 ctypes __del__