首页 > 解决方案 > 使用 ctypes 调用 argc/argv 函数

问题描述

我正在为 Python 的 c 代码创建一个包装器。c代码基本运行在终端,主要功能原型如下:

void main(int argc, char *argv[]){
f=fopen(argv[1],"r");
f2=fopen(argv[2],"r");

所以基本上读取的参数是终端中的字符串。我创建了以下 python ctype 包装器,但似乎我使用了错误的类型。我知道从终端传递的参数被读取为字符,但等效的 python 侧包装器给出以下错误:

import ctypes
_test=ctypes.CDLL('test.so')

def ctypes_test(a,b):
  _test.main(ctypes.c_char(a),ctypes.c_char(b))

ctypes_test("323","as21")



TypeError: one character string expected

我尝试添加一个字符,只是为了检查共享对象是否被执行,它确实像打印命令一样工作,但暂时直到共享对象中的代码部分需要文件名。我也试过 ctypes.c_char_p但得到。

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

根据评论中的建议更新如下:

def ctypes_test(a,b):
      _test.main(ctypes.c_int(a),ctypes.c_char_p(b))
ctypes_test(2, "323 as21")

然而得到同样的错误。

标签: pythonctypes

解决方案


使用适用于 Windows 的测试 DLL:

#include <stdio.h>

__declspec(dllexport) void main(int argc, char* argv[])
{
    for(int i = 0; i < argc; ++i)
        printf("%s\n",argv[i]);
}

此代码将调用它。 argv在 C中基本上是 a char**,所以 ctypes 类型是POINTER(c_char_p). 您还必须传递字节字符串,它不能是 Python 列表。它必须是一个 ctypes 指针数组。

>>> from ctypes import *
>>> dll = CDLL('./test')
>>> dll.main.restype = None
>>> dll.main.argtypes = c_int,POINTER(c_char_p)
>>> args = (c_char_p * 3)(b'abc',b'def',b'ghi')
>>> dll.main(len(args),args)
abc
def
ghi

推荐阅读