2017-02-15 3 views
1

Я новичок в Cython, поэтому, пожалуйста, простите меня, если это вопрос о нобе. Я пытаюсь изменить primes example на чистую реализацию C++ (.h/.cpp), которая затем заверяется файлом .pyx.Cython: зачем «дублировать символ»?

primes.h:

#include <list> 

std::list<int> primes2_c(int maxn); 

primes.cpp:

#include "primes.h" 

#include <list> 

std::list<int> primes2_c(int maxn) { 
    int n; 
    std::list<int> ret; 
    n = 2; 
    while (n < maxn) { 
     auto it = ret.begin(); 
     for (; it != ret.end() && n % *it != 0; it++); 
     if (it == ret.end()) { 
      ret.push_back(n); 
     } 
     n++; 
    } 

    return ret; 
} 

primes.pyx:

cdef extern from "primes.h": 
    list[int] primes2_c(int) 

def primes2(kmax): 
    ret = primes2_c(kmax) 
    return ret 

primes.setup:

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

setup(
    name='primes', 
    ext_modules=cythonize(Extension(
     'primes', 
     ['primes.pyx', 'primes.cpp'], 
     language='c++', 
     extra_compile_args=["-std=c++11"], 
     extra_link_args=["-std=c++11"], 
    )) 
) 

Затем я запускаю компиляцию и увидеть эту ошибку:

[cython (master)]$ python primes.setup build_ext --inplace 
running build_ext 
building 'primes' extension 
/usr/bin/clang -fno-strict-aliasing -Wsign-compare -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -arch i386 -arch x86_64 -g -I/Users/.../venv/cython/include -I/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m -c primes.cpp -o build/temp.macosx-10.6-intel-3.5/primes.o -std=c++11 
/usr/bin/clang -fno-strict-aliasing -Wsign-compare -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -arch i386 -arch x86_64 -g -I/Users/.../venv/cython/include -I/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m -c primes.cpp -o build/temp.macosx-10.6-intel-3.5/primes.o -std=c++11 
/usr/bin/clang++ -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/temp.macosx-10.6-intel-3.5/primes.o build/temp.macosx-10.6-intel-3.5/primes.o -o /Users/.../cython/primes.cpython-35m-darwin.so -std=c++11 
clang: warning: libstdc++ is deprecated; move to libc++ with a minimum deployment target of OS X 10.9 
clang: warning: libstdc++ is deprecated; move to libc++ with a minimum deployment target of OS X 10.9 
duplicate symbol __Z9primes2_ci in: 
    build/temp.macosx-10.6-intel-3.5/primes.o 
ld: 1 duplicate symbol for architecture i386 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
error: command '/usr/bin/clang++' failed with exit status 1 
[cython (master)]$ 

Я понимаю, что primes.pyx только считывает API из primes2_c(), но не реализации. Таким образом, единственная реализация, предусмотренная для той же функции, должна быть от ссылки до primes.cpp в primes.setup.

+0

Я не знаком с 'Cython.build', но из журнала сборки вы можете увидеть, что он компилирует' primes.o' из 'primes.cpp' * дважды *, а затем, когда он пытается построить' .so' он пытается связать в 'primes.o' дважды. – hobbs

+0

Ваши замечания верны. Я также заметил это. Мой ОП пытался спросить: «Почему реализация в primes.cpp связана дважды». – Roy

ответ

2

Не могли бы вы переименовать primes.cpp, например. primesc.cpp? Я думаю, primes.pyx скомпилирован в primes.cpp от Cython как часть сборки, поэтому есть столкновение с именем файла.

+0

Действительно, как вы сказали, проблема с именами '.cpp' и' .pyx' с использованием того же основного имени файла. Тем не менее, это неожиданно для меня, и я хотел бы подумать, что это проблема на стороне Cython, так как она генерирует любую папку сборки, и я ожидаю, что какой-либо промежуточный файл будет помещен в папку сборки. Но в любом случае, спасибо за ваш ответ! – Roy

+0

Я также обнаружил, что файл '.pyx' должен иметь то же имя, что и имя пакета, поскольку переименование его в нечто вроде' wrapper.pyx' приведет к 'ImportError: динамический модуль не определяет функцию экспорта модуля (PyInit_prime)' , Правила жесткого кодирования здесь очень просты для новичков IMHO. – Roy

Смежные вопросы