如何修复 'ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type' RaspberryPi

Posted

技术标签:

【中文标题】如何修复 \'ctypes.ArgumentError: argument 2: <type \'exceptions.TypeError\'>: wrong type\' RaspberryPi 中的错误【英文标题】:How to fix 'ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type' error in RaspberryPi如何修复 'ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type' RaspberryPi 中的错误 【发布时间】:2019-09-17 13:11:00 【问题描述】:

我想创建一个 C++ 库 (.so) 并在 Python 中使用它。 但正如您所见,C++ 函数参数是固定大小的数组。 创建如下所示的python源时, lib.ShiftRows.argypes=types.c_void_p, ?] 我应该在“?”中输入什么类型的数据部分?

而Python在实际使用上面的类时,为了声明与c++相同的数组变量,如何声明一个数组?

AES.cpp:

void AESS::ShiftRows( char state[0x04][0x04]) 
int i, j, k, tmp;

for (i = 0; i<4; i++) 
    for (j = 4 - i; j<4; j++) 
        tmp = state[i][0];
        for (k = 0; k<4 - 1; k++) 
            state[i][k] = state[i][k + 1];
        
        state[i][3] = tmp;
    
  


extern "C"

    AESS* AESS_new()return new AESS();
    void ShiftRows(AESS* aes,  char state[0x04][0x04]) aes->ShiftRows(state);

AESClass.py:

import ctypes

lib = ctypes.cdll.LoadLibrary('./libAESS.so')

class AESS():
    def __init__(self):
        lib.AESS_new.argtypes = []
        lib.AESS_new.restype = ctypes.c_void_p        

        lib.ShiftRows.argtypes=[ctypes.c_void_p , ?]
        lib.ShiftRows.restype= ctypes.c_void_p

        self.obj=lib.AESS_new()

    def ShiftRows(self, state):
        lib.ShiftRows(self.obj, state)

AES.py:

import numpy as np
from AESClass import AESS

state = np.zeros((4,4))

aes = AESS()

aes.ShiftRows(state)

【问题讨论】:

【参考方案1】:

检查[Python 3.Docs]: ctypes - A foreign function library for Python(数组部分)。

你可以这样做:

AESClass.py

CharArr4 = ctypes.c_char * 4
CharArr4Arr4 = CharArr4 * 4

class AESS():

# ...

        lib.ShiftRows.argtypes = [ctypes.c_void_p , CharArr4Arr4]

AES.py(使用[SciPy]: numpy.ctypeslib.as_array(obj, shape=None)):

import numpy as np
from AESClass import AESS, CharArr4Arr4


state_arr = CharArr4Arr4()  # Initialize the 4 X 4 array to 0
aes = AESS()
aes.ShiftRows(state_arr)

state = np.ctypeslib.as_array(state_arr)

或者反过来:

# ...
state = np.zeros((4, 4), dtype=np.int8)
# ...
aes.ShiftRows(np.ctypeslib.as_ctypes(state))

【讨论】:

如何用十六进制替换 state_arr[0][0]?我尝试了 'state_arr[0][0]=hex(10)' 但发生了错误。错误是“TypeError:需要一个整数”。所以我尝试了 c_int、c_byte、c_long 等...但没有成功 就像您通常使用 hex 数字操作一样:state_arr[0][0] = 0x0A(其值为 10)。 hex 返回一个字符串。 数组打印时,以十进制输出。我想在数组中放置一个十六进制值而不是十进制值。有没有办法将 Hexa 值放入数组中? 你在这里搞错了。该数组有一些值。我们以其中一个为例:11。在 base10 中表示为 11,而在 base16 中表示为 B(或在 base8 为 13),但 它是相同的数字。默认情况下(这是正常的,因为人类在 base10 中思考)。无论如何,打印与您之前的评论没有任何关系。如果你想以 hex 打印一个值,以十六进制打印它,但这不会改变它。 我知道你在说什么。不能将“W”放入 AES.py 的 CharArr4 数组中吗?我试过了,但是出现“需要整数”的错误。

以上是关于如何修复 'ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type' RaspberryPi的主要内容,如果未能解决你的问题,请参考以下文章

如何修复漏洞

如何修复WMI

PHP网站漏洞怎么修复 如何修补网站程序代码漏洞

如何修复这些漏洞? (npm audit fix 无法修复这些漏洞)

如何修复AppScan漏洞

如何在DOS环境下修复系统