未按预期将带有数组的嵌套ctypes结构传递给C库函数

2024-09-29 17:23:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面的C代码,可以从python脚本中使用。在

不幸的是,这只是一个自动生成的巨大库的节选,我无法更改。这里我只想将结构元素打印到一个控制台上,以演示出什么地方出了问题。在


// CFunc.h
#include <stdio.h>

typedef struct
{
    int npar;
    struct
    {
        int id;
        int value;
    } params[10];
} Data_t;

void Cfunc( const Data_t * d);


// CFunc.c

#include "CFunc.h"

void Cfunc( const Data_t * d)
{
    int inpar = 0;
    int maxnpar = 0;

    printf("%d:\n", d->npar);
    maxnpar = d->npar;

    inpar=0;
    while (maxnpar > inpar)
    {
        printf("  %d: %08x %08x\n", inpar, d->params[inpar].id, *(int*)&d->params[inpar].value);
        inpar++;
    }
}

它被编译并链接到共享库:

gcc -fPIC -c CFunc.c -o CFunc.o
gcc -shared -lrt -Wl,-soname,libCFunc.so.1 -o libCFunc.so CFunc.o

因此,我使用ctypes执行了以下实现:

^{pr2}$

所以我在初始化给定元组列表中的结构,在本例中只有2个,并调用C函数来查看其输出。在

paramlist = ( 
    ( 0x050000000, 0x00000000 ),  
    ( 0x050000001, 0x447a0000 ) )
temp = Data_t(paramlist)

pyFunc(temp)

不幸的是,输出结果与预期不符:

2:
0: 00000000 79948ef0
1: 00007fe5 00000000

你觉得我错过了什么吗?在


Tags: iddataincludevalueparams结构structint
1条回答
网友
1楼 · 发布于 2024-09-29 17:23:16

[Python 3]: ctypes - A foreign function library for Python。在

  • CPython中的结构不匹配
    • params数组而不是指针
  • 由于上述不一致性,您在Python中过度复杂了:
    • 你没有不完整的类型,所以你的结构可以静态定义

我重组了你的代码。在

dll.h:

#pragma once


typedef struct Data_ {
    int npar;
    struct
    {
        int id;
        int value;
    } params[10];
} Data;


void test(const Data *d);

dll.c

^{pr2}$

代码.py

#!/usr/bin/env python3

import sys
import ctypes


DLL = "./libdll.so"


class DataInner(ctypes.Structure):
    _fields_ = [
        ("id", ctypes.c_int),
        ("value", ctypes.c_int),
    ]


DataInnerArr10 = DataInner * 10


class Data(ctypes.Structure):
    _fields_ = [
        ("npar", ctypes.c_int),
        ("params", DataInnerArr10),
    ]

    def __init__(self, data):
        self.npar = len(data)
        self.params = DataInnerArr10(*data)


def main():
    dll_dll = ctypes.CDLL(DLL)
    test_func = dll_dll.test
    test_func.argtypes = [ctypes.POINTER(Data)]

    param_list = (
        (0x050000000, 0x00000000),
        (0x050000001, 0x447a0000),
    )

    d = Data(param_list)

    test_func(ctypes.byref(d))
    print("Done.")


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()

输出

[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054888242]> ls
code.py  dll.c  dll.h
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054888242]> gcc -shared -fPIC -o libdll.so dll.c
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054888242]> ls
code.py  dll.c  dll.h  libdll.so
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054888242]> python3 code.py
Python 3.6.4 (default, Jan  7 2018, 15:53:53)
[GCC 6.4.0] on cygwin

2:
  0: 50000000 00000000
  1: 50000001 447a0000
Done.

相关问题 更多 >

    热门问题