You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Python类中封装ctypes.Structure时遇初始化错误求助

问题:封装ctypes结构体到Python类时出现"too many initializers"错误

问题背景

需要通过ctypes.Structure向C语言传递结构体,Jupyter中的示例代码可正常运行,但封装为Python类时触发TypeError: too many initializers错误。


C语言代码(test.c)

struct DATA;

typedef struct DATA {
    int n;
    double *ina;
    double *outa;
} DATA;

void square_array2(DATA *data) {
    int i;
    for (i=0; i<data->n; i++) {
        data->outa[i] = data->ina[i]*data->ina[i];
    }
}

编译命令

gcc -shared -fPIC test.c -o test.so

可正常运行的Jupyter代码

import importlib
import numpy as np
import ctypes
from ctypes import CDLL, POINTER
from ctypes import c_size_t, c_double
from wurlitzer import pipes, STDOUT
%reload_ext wurlitzer
testlib = CDLL('test.so')
n=5
ina  = np.linspace(1.0,5.0,n)
outa = np.zeros(n,np.float64)

class Data(ctypes.Structure):
    _fields_ = [("n", ctypes.c_int),
                ("ina", ctypes.POINTER(ctypes.c_double)),
                ("outa", ctypes.POINTER(ctypes.c_double))]

data = Data(n,np.ctypeslib.as_ctypes(ina),np.ctypeslib.as_ctypes(outa))

print("initial array",ina)
testlib.square_array2.restype = None
testlib.square_array2(ctypes.byref(data))
print("final array",outa)

出错的封装类代码

import ctypes

from ctypes import CDLL, POINTER 
from ctypes import c_size_t, c_double, c_int 
from io import StringIO 
from wurlitzer import pipes, STDOUT


class Data(ctypes.Structure): 
    _fields_ = [("n", ctypes.c_int), 
                ("ina", ctypes.POINTER(ctypes.c_double)), 
                ("outa", ctypes.POINTER(ctypes.c_double))]

class testClib(Data):   #尝试继承Data类

    def __init__(self):
        # 加载库
        self.lib = CDLL("test.so")
    
    def square_array2(self,ina,outa):

        n, = ina.shape
    
        # 出错的代码行
        data = Data(n,np.ctypeslib.as_ctypes(ina),np.ctypeslib.as_ctypes(outa))
    
        out = StringIO()

        with pipes(stdout=out, stderr=STDOUT):
                
            self.lib.square_array2.restype = None
            self.lib.square_array2(ctypes.byref(data))
        
        stdout = out.getvalue()
        print(stdout)
        print(ina)
        print(outa)

错误信息

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[51], line 3
      1 # lets add this in a wrapper routine
----> 3 ctest.square_array2(ina,outa)

File ~/WORK/PYTHONLIB/ctypesTEST/ctypesTEST3.py:46, in testClib.square_array2(self, ina, outa)
     42 def square_array2(self,ina,outa):
     44     n, = ina.shape
---> 46     data = Data(n,np.ctypeslib.as_ctypes(ina),np.ctypeslib.as_ctypes(outa))
     48     out = StringIO()
     50     with pipes(stdout=out, stderr=STDOUT):

TypeError: too many initializers

解决方案

问题根源在于testClib继承了Data类,而ctypes.Structure的子类被继承时,会破坏原结构体的初始化逻辑——子类的构造函数会干扰父类Data的实例化参数解析。

修复方法:移除testClib对Data类的继承,因为testClib是封装C库的工具类,不需要继承结构体类型。修改后的代码如下:

import ctypes
import numpy as np

from ctypes import CDLL, POINTER 
from ctypes import c_size_t, c_double, c_int 
from io import StringIO 
from wurlitzer import pipes, STDOUT


class Data(ctypes.Structure): 
    _fields_ = [("n", ctypes.c_int), 
                ("ina", ctypes.POINTER(ctypes.c_double)), 
                ("outa", ctypes.POINTER(ctypes.c_double))]

class testClib:   # 移除对Data的继承

    def __init__(self):
        # 加载库
        self.lib = CDLL("test.so")
        # 提前设置函数返回类型,避免重复设置
        self.lib.square_array2.restype = None
    
    def square_array2(self,ina,outa):
        n, = ina.shape
        # 现在可正常实例化Data结构体
        data = Data(n, np.ctypeslib.as_ctypes(ina), np.ctypeslib.as_ctypes(outa))
        
        out = StringIO()
        with pipes(stdout=out, stderr=STDOUT):
            self.lib.square_array2(ctypes.byref(data))
        
        stdout = out.getvalue()
        print(stdout)
        print("输入数组:", ina)
        print("输出数组:", outa)

调用示例

ctest = testClib()
n=5
ina = np.linspace(1.0,5.0,n)
outa = np.zeros(n,np.float64)
ctest.square_array2(ina, outa)

修改后,结构体实例化不再出现参数数量错误,C函数可正常处理数组求平方逻辑。

内容的提问来源于stack exchange,提问作者Robert Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:31:08