使用 c_types 改进 C 代码的 Python 包装器

Improving a Python Wrapper for C code using c_types

我正在使用 c_types.

在 Python 上为 C 代码开发一个简单的包装器

我的问题如下:

在 Python 代码中,据我所知,我创建了一个名为 args 的变量,用于将数据类型从 python 编组到 C。我的问题是我必须输入每个参数 (str.encode(sys.argv[0]), str.encode(sys.argv[1]), ...) 这是...unPythonic.

如果我不知道我的函数中将输入多少个参数,比如可选参数,该怎么办?

我已经试过了:

   args=(ctypes.c_char_p * (len(sys.argv)))(str.encode(" ".join(sys.argv)))

但是它将所有参数放在第一个参数中,意思是 argv[0]="pyclib.py 1 2 3 4" 那么,有没有人有想法帮助我? 感谢您的时间。 这是它现在的样子:

Python代码:

import signal
import ctypes 
import os 
import sys 

if __name__ == "__main__" :
    print("==================")
    print("Begining of Python program")
    print("==================")
    
    # Retrieving paht for .so file
    libname = os.path.abspath(os.path.join(os.path.dirname(__file__),"clib.so"))

    # Setting argtypes and return types for C function
    LIBC = ctypes.CDLL(libname)
    LIBC.main.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p),]
    LIBC.main.restypes=[ctypes.c_int,]

    # Setting argtypes 
    args=(ctypes.c_char_p * (len(sys.argv)))(str.encode(sys.argv[0]),str.encode(sys.argv[1]),str.encode(sys.argv[2])) #QUESTION

    # Creating status variable which will be used to get exit code of C called function
    status = LIBC.main(len(args),args)

    # Printing exit code 
    print("C function exit code : ", status)
    signal.signal(signal.SIGINT,signal.SIG_DFL)
    input()

    print("==================")
    print("End of Python program")
    print("==================")

C代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>


volatile sig_atomic_t flag = 0 ;

void raise_flag(int sig)
{
    flag=1;
}

int main(int argc, char* argv[])
{
    printf("\n==================\n");
    printf("Begining of C program\n");
    printf("=================\n");
    
    signal(SIGINT,raise_flag);

        printf("argc :%i \n",argc);

    for (int i = 0 ; i < argc ; i++ )
    {
        printf("Argument %i is %s \n", (i+1), argv[i]) ;
    }
printf("=========\n");
printf("End of C program\n");
printf("========\n");
 return 0 ;

}

生成文件:

all: test

clean:
    rm -f *.o *.so *.html

clib.so: clib.o
    gcc -shared -o clib.so clib.c -fPIC

clib.o: clib.c
    gcc -Wall -Werror clib.c -fPIC

test: clib.so
    chmod 777 pyclib.py
    python pyclib.py 1 2 3 4 

不确定这是您想要的,但是,您可以理解列表,然后 'expand' 使用星号运算符的列表:

args=(ctypes.c_char_p * len( sys.argv ))( *[str.encode(i) for i in sys.argv] )

此外,从可读性的角度来看,这非常难看。我会分开一行以使 reader:

清楚
C_charPointer_array = ctypes.c_char_p * len( sys.argv )
EncodedArgsList     = [str.encode( i ) for i in sys.argv]
args                = C_charPointer_array( *EncodedArgsList )