Tenho uma biblioteca compartilhada expondo uma função:
const char* foo(const char* s);
Para chamá-lo do Python usando ctypes, posso fazer o seguinte:
import ctypes
foo = ctypes.cdll.LoadLibrary('foo.so')
foo.foo.argtypes = [ctypes.c_char_p]
foo.foo.restype = ctypes.c_char_p
print(foo.foo('Hello World!'.encode('utf8')).decode('utf8'))
Existe uma maneira de incorporar o texto encode/decode('utf8')
dentro do próprio tipo? Quero fazer o seguinte:
foo.foo.argtypes = [c_utf8_p]
foo.foo.restype = c_utf8_p
print(foo.foo('Hello World!'))
Consegui lidar argtypes
com o seguinte:
class c_utf8_p:
@classmethod
def from_param(cls, obj: str):
return obj.encode('utf8')
Mas não consigo descobrir o tipo de retorno. restype
A documentação diz que atribuí-lo a qualquer coisa que não seja um ctypes
tipo está obsoleto, além de truncar o valor, int
o que destrói ponteiros de 64 bits. Gostaria de evitar o uso, errcheck
pois, logicamente, não estou verificando nenhum erro, além de exigir a definição de dois atributos para cada função.
Não há uma maneira documentada de fazer o que você quer com
.restype
. Acho que você tem duas opções:Use
.errcheck
, pois permite acesso ao valor de retorno real e pode retornar uma versão modificada. Uma vantagem é que ele define apenas um atributo extra por função, em comparação com o nº 2...Função wrapper. Seria necessária para cada função que precisasse de pós-processamento.
Exemplos:
Usando
.errcheck
:Saída:
Usando um wrapper:
Saída: