在 Pybind11 中使用自动转换
Using automatic conversion in Pybind11
我试图通过从 Python 调用一些 C++ 函数来利用它们。为此,我试图构建一个小型演示函数来向自己展示 python 类型如何转换为 C++ 类型。根据 Pybind11 文档,如果您在 header 中包含 pybind11/stl.h
,许多常见类型应该会自动转换:
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 Studio17\Professional\VC\Tools\MSVC.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 Studio17\Professional\VC\Tools\MSVC.16.27023\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio17\Professional\VC\Tools\MSVC.16.27023\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\lib.0.17763.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\lib.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
问题很简单:header guards 对 .cpp 文件不起作用,所以解决方案是将 my.cpp 分解为 my.hpp 和 my.cpp 文件并包含 [= wrap.cpp 文件中的 15=] 文件。
在我完成的几个演示中,到目前为止只有这个演示需要这样做。我不确定为什么这个演示需要拆分文件,而我直接包含 .cpp 文件的其他演示则不需要。
#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"
将 my.cpp
的内容复制粘贴到 include 指令所在的位置。这与 python.
中的导入不同
在其他情况下不会发生这种情况可能是因为您没有link cpp 文件;无论包含 cpp 文件是否违反惯例,都不要这样做。
我试图通过从 Python 调用一些 C++ 函数来利用它们。为此,我试图构建一个小型演示函数来向自己展示 python 类型如何转换为 C++ 类型。根据 Pybind11 文档,如果您在 header 中包含 pybind11/stl.h
,许多常见类型应该会自动转换:
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 Studio17\Professional\VC\Tools\MSVC.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 Studio17\Professional\VC\Tools\MSVC.16.27023\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio17\Professional\VC\Tools\MSVC.16.27023\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\lib.0.17763.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\lib.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
问题很简单:header guards 对 .cpp 文件不起作用,所以解决方案是将 my.cpp 分解为 my.hpp 和 my.cpp 文件并包含 [= wrap.cpp 文件中的 15=] 文件。
在我完成的几个演示中,到目前为止只有这个演示需要这样做。我不确定为什么这个演示需要拆分文件,而我直接包含 .cpp 文件的其他演示则不需要。
#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"
将 my.cpp
的内容复制粘贴到 include 指令所在的位置。这与 python.
在其他情况下不会发生这种情况可能是因为您没有link cpp 文件;无论包含 cpp 文件是否违反惯例,都不要这样做。