Как обернуть C внутренний l oop в Cython - PullRequest
1 голос
/ 13 февраля 2020

Python программист с практически нулевым знанием C / Cython здесь. Любая помощь приветствуется.

Цель

Я хотел бы заменить внешний l oop этого C -файла на python:

"dummy_outer. c ":

// Try to convert the c file into a cython wrapped c-file that maintains the state.
#include <stdio.h>  

void do_inner_stuff(int i);

int state = 0;

int main(void)
{
    for ( int x = 1; x <= 10; x++ )
      {
        do_inner_stuff(x);
      }
}

void do_inner_stuff(int i){
    state += i;
    printf("State is: %d\n", state);
}

Итак, я хочу получить файл python с циклом от 1 до 10 и вызовом функции do_inner_stuff(i) из C.

Что я сделал

  1. Я создал c -файл только с внутренними внутренностями:

"dummy_inner. c"

// Removed the main function and only kept the state and inner functions.
// Python should loop and call the inner function with the appropriate value.

#include <stdio.h>  

void do_inner_stuff(int i);

int state = 0;

void do_inner_stuff(int i){
    state += i;
    printf("State is: %d\n", state);
}
Написал файл Cython.

"dummy.pyx":

cdef extern from "dummy_inner.c":
    void do_inner_stuff(int state)

def py_main() -> None:
    do_inner_stuff(44)
Написал установочный файл:

"setup.py":

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

dummy_extension = Extension(
    name="dummy",
    sources=["dummy.pyx"],
    libraries=["dummy_inner"]
)
setup(
    name="dummy",
    ext_modules=cythonize([dummy_extension])
)
Написал файл компиляции:
g++ -Wall -o dummy_outer dummy_outer.c -lm -O
g++ -Wall -o dummy_inner dummy_inner.c -lm -O

echo "Running c version:"
./dummy_outer
echo "Running python-wrapped version"
???

Проблемы

У меня две проблемы.

  1. Когда я пытаюсь скомпилировать файл c, он жалуется на отсутствие main (но мне не нужно main, мой python файл будет иметь main):
$ sh dummy.sh

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Когда я пытаюсь запустить установку Cython, я получаю сообщение об ошибке (я понятия не имею, что не так):
$ python setup.py build_ext --inplace

ld: library not found for -ldummy_inner
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: command 'gcc' failed with exit status 1

1 Ответ

0 голосов
/ 14 февраля 2020

Ничего себе, это проще, чем я думал с ctypes.

"inner. c":

// Removed the main function and only kept the state and inner functions.
// Python should loop and call the inner function with the appropriate value.

#include <stdio.h>  

void do_inner_stuff(int i);

int state = 0;

void do_inner_stuff(int i){
    state += i;
    printf("State is: %d\n", state);
}

"external.py":

from ctypes import cdll
from ctypes import c_char_p

inner_lib = cdll.LoadLibrary("inner.so")

for i in range(10):
    inner_lib.do_inner_stuff(i)

Тогда:

gcc -o inner.so -shared -fPIC inner.c

и:

$ python outer.py

State is: 0
State is: 1
State is: 3
State is: 6
State is: 10
State is: 15
State is: 21
State is: 28
State is: 36
State is: 45
...