我尝试使用cTypes从python向C函数传递一个字符串(作为指针)。
c函数需要获取一个指向字符串(字符数组)的指针,但我还没有成功地让它与多个字符一起工作,但我唯一的成功(有点成功,看看输出)是1个字符,并希望得到一些帮助!
我需要发送一个字符串的指针到char -(unsigned char * input)
我的Python代码:
def printmeP(CHAR):
print("In Print function")
print(CHAR)
c_sends = pointer(c_char_p(CHAR.encode('utf-8')))
print("c_sends: ")
print(c_sends[0])
python_p_printme(c_sends)
print("DONE function - Python")
print(c_sends[0])
return
from ctypes import c_double, c_int,c_char, c_wchar,c_char_p, c_wchar_p, pointer, POINTER,create_string_buffer, byref, CDLL
import sys
lib_path = '/root/mbedtls/programs/test/mylib_linux.so' .format(sys.platform)
CHAR = "d"
try:
mylib_lib = CDLL(lib_path)
except:
print('STARTING...' )
python_p_printme = mylib_lib.printme
python_p_printme.restype = None
printmeP(CHAR)
我的C代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printme(char * param) {
printf("\nStart c Function!\n");
printf("%s\n Printing param\n ", param);
char add = '!';
strncat(param, &add, 1);
printf("%s\n Printing param\n ", param);
printf("Function Done - c\n");
}
我的输出:
In Print function
d <--- this is what i am sending
c_sends:
b'd' <--- this is after encoding
��[� <-------------=|
Printing param |
��[� | This is the c code print
Printing param | **Question:** Why does it print '�' and no what's supposed to be printed
Function Done - c <--=|
DONE function - Python
b'd!' <--------------------- this is the last print that prints after the change.
希望能得到一些帮助,感谢所有参与的人:)
真诚的,罗伊
2条答案
按热度按时间a64a0gku1#
存在若干问题:
1.为函数定义
.argtypes
。它将捕获传递不正确参数的错误。添加下面的行,并注意它是复数,是参数类型的元组。逗号构成一个1元组:python_p_printme.argtypes = c_char_p,
1.一旦你做了这个修改,你会得到一个错误,因为这段代码:
c_sends = pointer(c_char_p(CHAR.encode('utf-8')
实际上是发送一个C
char**
(指向c_char_p的指针)。一旦你正确地设置了argtypes,你就可以用一个字节字符串调用这个函数,它就会工作。您的函数变为:1.还有一个更微妙的问题。虽然程序在这一点上看起来可以工作,但Python字符串是不可变的,因此如果调用的函数需要一个可变字符串,则必须使用
create_unicode_buffer
(对于c_wchar_p)或create_string_buffer
(对于c_char_p)分配一个可变缓冲区;否则,C代码中的strcat
将损坏Python字符串。下面是一个完整的例子:
test.cpp
test.py
输出:
注意,如果C函数不改变缓冲区,例如C参数是
const char*
,则不需要使用create_string_buffer
。然后你可以调用printme(b'test string')
。snz8szmq2#
你可以使用create_string_buffer。
文档可以在这里找到:https://docs.python.org/3/library/ctypes.html#ctypes.create_string_buffer
ctypes.create_string_buffer(init_or_size,size=None)
这个函数创建一个可变字符缓冲区。返回的对象是c_char的ctypes数组。
init_or_size必须是指定数组大小的整数,或者是用于初始化数组项的bytes对象。
使用
buf.value.decode("utf-8")
可以将缓冲区转换回UTF-8 python字符串。你的C代码库的一个小例子可能看起来像这样:
它将输出:
在控制台上。