使用 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 )
我正在使用 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 )