python - 使用 c_types 改进 C 代码的 Python Wrapper
问题描述
我正在使用 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" 那么,有没有人有帮助我的想法?感谢您的时间。这是现在的样子:
蟒蛇代码:
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
解决方案
不确定这是您所追求的,但是,您可以进行列表理解,然后使用星号运算符“扩展”列表:
args=(ctypes.c_char_p * len( sys.argv ))( *[str.encode(i) for i in sys.argv] )
此外,从可读性的角度来看,这非常难看。我会拆分单行以使读者清楚:
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# - 为什么没有为此代码调用析构函数
- javascript - JavaScript。字典键不是字符串?
- angular - Ionic PWA 与传统的 Ionic 是分开的吗?
- grails - Spring 安全核心插件 - 如何从控制器访问用户 ID
- angular - 请求语音识别 iOS、Ionic 3 的权限
- openshift - Openshift oc 工具和 web ui 超时:来自服务器的错误 (ServerTimeout)
- sql - 我收到异常“形式参数“@param1”未声明为 OUTPUT 参数,但在请求的输出中传递了实际参数”
- javascript - 复选框,本地存储上的单选按钮
- vue.js - Vue中如何在不同组件之间搭建事件的桥梁?
- docker - 带有来自临时容器的复制数据的 Docker 挂载卷