Python ctypes AttributeError: function not found

Рейтинг: 2Ответов: 1Опубликовано: 30.07.2023

Я пытаюсь совместить Python с C при помощи dll
Файл main.c:

#include <stdio.h>

void print(char *str) {
    printf("%s", str);
}

При сборке в dll никаких ошибок нет, использую clang 16.0.0 x64 и команды:

clang -c main.c -o main.o
clang -shared main.o -o main.dll

Но стоит мне запустить main.py, как я получаю ошибку:

Traceback (most recent call last):
  File "E:\main.py", line 5, in <module>
    module.print('Hello!')
    ^^^^^^^^^^^^
  File "D:\languages\python\Lib\ctypes\__init__.py", line 389, in __getattr__
    func = self.__getitem__(name)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "D:\languages\python\Lib\ctypes\__init__.py", line 394, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: function 'print' not found

Файл main.py:

import ctypes


module = ctypes.CDLL('./main.dll')
module.print('Hello!')

Использую python 3.10.4 x64

В чём проблема, и что я делаю не так?

Ответы

▲ 1Принят

Нужно добавить extern "C"перед объявлением функции:

extern "C" void print(char *str)
{
    printf("%s", str);
}

Также нужно описать аргументы и возвращаемое значение в коде на Python следующим образом:

module.print.restype = None #Указываем, что функция ничего не возвращает
module.print.argtypes = ctypes.c_char_p #Указываем, что функция принимает в качестве аргумента указатель на массив символов

Чтобы передать в функцию строку в виде массива символов, нужно её перекодировать так:

module.print('Hello!'.encode('utf-8'))