python - 在Python中使用Ctypes读取Dll的双c结构

标签 python c structure ctypes

我对这个问题做了很多研究。但是没有地方,我找不到它。我试图通过调用 c dll 来调用双 c 结构。

我的问题是,我在 python 中声明“类结构”的方法是否正确?我没想到我就在路上。因为即使我想从 dll 调用函数,它也没有输出任何内容。

[Visual C++/C]

我确实尝试过 C 语法代码,

typedef sturct {
    int nBoardNum;
    struct{
        char  pBoardName[16];
        int   nBoardID;
    }BOARDINDEX[8];
}AAPBOARDINFO, *PAAPBOARDINFO;

HANDLE AcapOpen(char* cpBoardName, int nBoardNo, int nCh)

[Python]

我像这样改变了Python语法。

import ctypes as c

class BOARDINDEX(c.Structure):
    _field_ = [("nBoardName", c.c_char_p * 16),("nBoardID", c.c_int)]

class AAPBOARDINFO(c.Structure):
    _field_ = [("nBoardNum", c.c_int), ("BOARDINDEX", BOARDINDEX * 8)]

AapLib2 = c.WinDLL("AapLib2.dll")

BoardName = ["ABC","FWD","HGW"]
BoardNo = 0
ch = 1

output = Open(BoardName, BoardNo, ch)

def Open(BoardName, BoardNo, ch)

    func = AapLib2.AcapOpen
    func.argtypes = [c.POINTER(BOARDINDEX),c.c_int, c.c_int]
    func.restype = c.c_int

    ref = BOARDINDEX()

    res = func(c.byref(ref.nBoardName),BoardNo, ch)
    return res

调用 Open() 函数时没有任何结果...

请考虑我的请求,任何答案都会很好......

最佳答案

您需要了解的一切都可以在 [Python.Docs]: ctypes - A foreign function library for Python 中找到.

代码有几个问题:

  1. 结构成员在_fields_(不是_field_)属性中指定

  2. char pBoardName[16] 映射到 ctypes.c_char * 16(不是c_char_p)

  3. HANDLE 应映射到 wintypes.HANDLE

  4. CPython 的函数原型(prototype)不同

  5. 最好避免使用像 AapLib2 这样的全局变量,但我保留它们不变,因为它们超出了问题范围

#1.#3. 将生成 U定义B行为!检查[SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)了解更多详情。

这是您的代码的修改版本。不用说,我没有实际测试它,因为我没有 .dll:

#!/usr/bin/env python

import ctypes as cts
import sys
from ctypes import wintypes as wts


class BOARDINDEX(cts.Structure):
    _fields_ = [
        ("nBoardName", cts.c_char * 16),
        ("nBoardID", cts.c_int),
    ]


class AAPBOARDINFO(cts.Structure):
    _fields_ = [
        ("nBoardNum", cts.c_int),
        ("BOARDINDEX", BOARDINDEX * 8),
    ]


def open_board(board_name, board_no, ch):
    AcapOpen = aaplib2.AcapOpen
    AcapOpen.argtypes = (cts.c_char_p, cts.c_int, cts.c_int)
    AcapOpen.restype = wts.HANDLE
    ref = BOARDINDEX(board_name, board_no)  # Probably this line should be replaced by the 3 (commented) ones below (AcapGetBoardInfo prototype would have to be specified as well)
    #abi = AAPBOARDINFO()
    #AcapGetBoardInfo(cts.byref(abi))
    #ref = abi.BOARDINDEX[0]
    res = AcapOpen(ref.nBoardName, ref.nBoardID, ch)
    return res


def main(*argv):
    board_names = (
        "ABC",
        "FWD",
        "HGW",
    )
    board_no = 0
    ch = 1
    aaplib2 = cts.WinDLL("AapLib2.dll")
    output = open_board(board_names[0], board_no, ch)
    print(output)


if __name__ == "__main__":
    print("Python {:s} {:03d}bit 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.\n")
    sys.exit(rc)

让我知道这是如何实现的。

关于python - 在Python中使用Ctypes读取Dll的双c结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57282055/

相关文章:

python - 如何在 tkinter 中创建一个自调整大小的按钮网格?

c - 函数的隐式声明

c++ - 这个typedef是什么意思?

c - 如何在结构体中使用指针?

c++ - sizeof(struct)... 给出错误结果,VS 2010

python - 在 Map reduce Python 中按文件和按日期计数

python - Python 2 中的字节数组未按预期运行

python - 父类(super class)的实例变量的值在子类的实例中保持不变

c - 具有依赖关系的类似 Arduino 的 Makefile ......?

c++ - 复制调用功能