Использование автоматического преобразования c в Pybind11 - PullRequest
2 голосов
/ 13 января 2020

Я пытаюсь воспользоваться некоторыми функциями C ++, вызывая их из Python. Для этого я пытался создать небольшую демонстрационную функцию, чтобы показать, как python типы преобразуются в типы C ++. Согласно документации Pybind11, если вы включите pybind11/stl.h в заголовок, автоматическое преобразование c должно выполняться для многих распространенных типов:

https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html

Что не так со следующим кодом?

my. cpp

#include <vector>
int add_these(std::vector<int> &v) {
    int sum=0;
    for (int i = 0; i < v.size(); ++i) {
            sum += v[i];
    }
    return sum;
    }

wrap. cpp

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <vector>
#include "my.cpp"
namespace py=pybind11;
PYBIND11_MODULE(python_example, m) {
    m.def("addup", &add_these);
#ifdef VERSION_INFO
    m.attr("__version__") = VERSION_INFO;
#else
    m.attr("__version__") = "dev";
#endif
}

Я успешно скомпилировал другие созданные мной демонстрации, поэтому я не думаю, что это ошибка моего процесса компиляции. Но при компиляции этой демонстрации я получаю эту ошибку:

 wrap.cpp
    creating C:\Users\scottjr1\AppData\Local\Temp\pip-req-build-wyi5ezw1\build\lib.win-amd64-3.7
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:c:\users\scottjr1\appdata\python\python37\libs /LIBPATH:c:\users\scottjr1\appdata\python\python37\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x64" /EXPORT:PyInit_python_example build\temp.win-amd64-3.7\Release\src/my.obj build\temp.win-amd64-3.7\Release\src/wrap.obj /OUT:build\lib.win-amd64-3.7\python_example.cp37-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.7\Release\src\python_example.cp37-win_amd64.lib
    wrap.obj : error LNK2005: "int __cdecl add_these(class std::vector<int,class std::allocator<int> > &)" (?add_these@@YAHAEAV?$vector@HV?$allocator@H@std@@@std@@@Z) already defined in my.obj
       Creating library build\temp.win-amd64-3.7\Release\src\python_example.cp37-win_amd64.lib and object build\temp.win-amd64-3.7\Release\src\python_example.cp37-win_amd64.exp
    build\lib.win-amd64-3.7\python_example.cp37-win_amd64.pyd : fatal error LNK1169: one or more multiply defined symbols found
    error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX86\\x64\\link.exe' failed with exit status 1169

Ответы [ 2 ]

1 голос
/ 13 января 2020

Проблема была проста: средства защиты заголовков не работают с файлами. cpp, поэтому было решено разбить мои файлы. cpp на my.hpp и my. cpp и включить файл my.hpp в файле обертки. cpp.

Из нескольких демо, которые я сделал, пока это требовалось только для этой демонстрации. Я не уверен, почему для демонстрации необходимо разбить файл, но не для тех, где я включил файлы. cpp напрямую.

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

#include "my.cpp" неверно. Заменить на #include "my.h".

my.h должно содержать:

#include <vector>
int add_these(std::vector<int> const &v);

объявление вашей функции.

и my.cpp должны содержать определение:

#include "my.h"
int add_these(std::vector<int> const&v) {
  int sum=0;
  for (int i = 0; i < v.size(); ++i) {
      sum += v[i];
  }
  return sum;
}

ошибка, которую вы видите, состоит в том, что у вас есть два .cpp файла, которые содержат определение функции; это не разрешено в C ++.

#include "my.cpp" copy вставляет содержимое my.cpp, где находится директива include. Это не то же самое, что импорт в python.

Это не происходило в других случаях, возможно, потому что вы не связали файл cpp; не считая cpp соглашения о нарушении файлов, не делайте этого.

...