获取链接器错误 LNK2001:使用 Pybind11 构建 Python 扩展时无法解析的外部符号 PyInit_your_module_name

Getting linker error LNK2001: unresolved external symbol PyInit_your_module_name when building a Python extension using Pybind11

我正在尝试使用 Pybind11 构建一个 Python 扩展,我相信我正确设置了所有库、链接器相关对象。但是我得到了这个奇怪的链接器错误! 这是我的示例输入

#include <string>
#include <vector>

#include <torch/script.h>
#include <pybind11/pybind11.h>
namespace py = pybind11;

#include <FV/FV.h>
//template <class T>
class PyManager 
{
public:
    PyManager(std::string model_path, std::string img_bank_folder_root, std::string cache_folder,
        std::string pnet, std::string rnet, std::string onet, bool rebuildCache)
    {
        auto config = FV::Load_Default_Settings();
        //...
        fv = std::make_shared<FV>(config);
    }


    int AddUser(std::string user_id, std::string img_fldr_path)
    {
        return fv->AddNewUser(user_id, img_fldr_path);
    }
    int RemoveUser(std::string user_id)
    {
        return fv->RemoveUser(user_id);
    }
    int UpdateUser(std::string user_id, std::string new_images_folder_path)
    {
        return fv->UpdateUser(user_id, new_images_folder_path);
    }
    int UpdateUsersInBulk(std::vector<std::string> userIDs, std::string ID_folders_path, bool is_delete_granted = true, bool show_dbg_info = true)
    {
        return fv->UpdateUsersInBulk(userIDs, ID_folders_path, is_delete_granted, show_dbg_info);

    }
    int RenameId(std::string old_id, std::string new_id)
    {
       return fv->RenameUserID(old_id, new_id);
    }

private:
    std::shared_ptr<FV> fv;
};

PYBIND11_MODULE(PythonUserManager, m) {
    py::class_<PyManager>(m, "Manager")
        .def(py::init<std::string, std::string, std::string, std::string, std::string, std::string, bool>())
        .def("add", &PyManager::AddUser)
        .def("remove", &PyManager::RemoveUser)
        .def("update", &PyManager::UpdateUser)
        .def("rename", &PyManager::RenameId)
        .def("update_in_bulk", &PyManager::UpdateUsersInBulk);
}

这就是我构建扩展的方式 (setup.py):


import os, sys
from os import environ, getcwd
from distutils.core import setup, Extension
from distutils import sysconfig
import getpass 
cpp_args = ['/std:c++17']

user = getpass.getuser()
sfc_module = Extension(
    'PythonManager_Pybind11', sources=['PythonManager_Pybind11.cpp', 'D:/cpp/port/LibtorchPort/Dependencies/include/messages/Config.pb.cc'],

    include_dirs=['pybind11/include',
                  f'C:/Users/{user}/Anaconda3/include',
                  f'C:/Users/{user}/Anaconda3/include/pybind11/',
                  "D:/External Libs/Opencv3.4.10_vc14_vc15/opencv3.4/include",
                  "D:/cpp/port/LibtorchPort/Dependencies/include",
                  "D:/cpp/port/LibtorchPort/Dependencies/libtorch-release-latest/libtorch/include",
                  "D:/cpp/port/LibtorchPort/Dependencies/libtorch-release-latest/libtorch/include/torch/csrc/api/include",
                  f'C:/Users/{user}/Anaconda3/Library/include',
                  f'C:/Users/{user}/Anaconda3/Lib/site-packages/numpy/core/include'],

    library_dirs=[# python3.6.7: f'C:/Users/{user}/Anaconda3/pkgs/openblas-0.3.3-h535eed3_1001/Library/lib',
                  "D:/cpp/port/LibtorchPort/x64/Release",
                  "D:/External Libs/Opencv3.4.10_vc14_vc15/opencv3.4/x64/vc14/lib",
                  "D:/cpp/port/LibtorchPort/Dependencies/libtorch-release-latest/libtorch/lib",
                  f'C:/Users/{user}/Anaconda3/libs',
                  f'C:/Users/{user}/Anaconda3'],

    libraries=['FV', 'libprotobuf-lite','libprotobuf','libprotoc','c10','asmjit','clog','cpuinfo','dnnl','fbgemm','mkldnn','torch','torch_cpu'],
    language='c++',
    extra_compile_args=cpp_args,
    )

setup(
    name='UserManager',
    version='1.0',
    description='Python package with PythonExtension C++ extension (PyBind11)',
    ext_modules=[sfc_module],
)

导致以下链接器错误:

    creating C:\Users\User\AppData\Local\Temp\pip-req-build-xl1k7s1f\build\lib.win-amd64-3.7
    C:\Program Files (x86)\Microsoft Visual Studio19\Enterprise\VC\Tools\MSVC.27.29110\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:D:/Codes/fac_ver/cpp/port/LibtorchPort/x64/Release "/LIBPATH:D:/External Libs/Opencv3.4.10_vc14_vc15/opencv3.4/x64/vc14/lib" /LIBPATH:D:/Codes/fac_ver/cpp/port/LibtorchPort/Dependencies/libtorch-release-latest/libtorch/lib /LIBPATH:C:/Users/User/Anaconda3/libs /LIBPATH:C:/Users/User/Anaconda3 /LIBPATH:C:\Users\User\Anaconda3\libs /LIBPATH:C:\Users\User\Anaconda3\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio19\Enterprise\VC\Tools\MSVC.27.29110\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio19\Enterprise\VC\Tools\MSVC.27.29110\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK.8\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\lib.0.18362.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\lib.0.18362.0\um\x64" FV.lib libprotobuf-lite.lib libprotobuf.lib libprotoc.lib c10.lib asmjit.lib clog.lib cpuinfo.lib dnnl.lib fbgemm.lib mkldnn.lib torch.lib torch_cpu.lib /EXPORT:PyInit_PythonManager_Pybind11 build\temp.win-amd64-3.7\Release\PythonManager_Pybind11.obj build\temp.win-amd64-3.7\Release\Codes/fac_ver/cpp/port/LibtorchPort/Dependencies/include/messages/Config.pb.obj /OUT:build\lib.win-amd64-3.7\PythonManager_Pybind11.cp37-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.7\Release\PythonManager_Pybind11.cp37-win_amd64.lib
    LINK : error LNK2001: unresolved external symbol PyInit_PythonManager_Pybind11
    build\temp.win-amd64-3.7\Release\PythonManager_Pybind11.cp37-win_amd64.lib : fatal error LNK1120: 1 unresolved externals
    error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\link.exe' failed with exit status 1120

我在这里错过了什么?

好吧,我犯了一个愚蠢的错误!似乎在定义 PYBIND11_MODULE 时,名字和 setup() 中使用的名称需要与源文件相同,即在我的例子中是 PythonManager_Pybind11.cpp。这就是链接器抱怨作为主要源文件的实际对象的原因。
进行这些更改后,现在一切正常。

这是经过这些小改动后的样子:

#include <string>
#include <vector>

#include <torch/script.h>
#include <pybind11/pybind11.h>
namespace py = pybind11;

#include <FV/FV.h>
//template <class T>
class PyManager 
{
public:
    PyManager(std::string model_path, std::string img_bank_folder_root, std::string cache_folder,
        std::string pnet, std::string rnet, std::string onet, bool rebuildCache)
    {
        auto config = FV::Load_Default_Settings();
        //...
        fv = std::make_shared<FV>(config);
    }


    int AddUser(std::string user_id, std::string img_fldr_path)
    {
        return fv->AddNewUser(user_id, img_fldr_path);
    }
    int RemoveUser(std::string user_id)
    {
        return fv->RemoveUser(user_id);
    }
    int UpdateUser(std::string user_id, std::string new_images_folder_path)
    {
        return fv->UpdateUser(user_id, new_images_folder_path);
    }
    int UpdateUsersInBulk(std::vector<std::string> userIDs, std::string ID_folders_path, bool is_delete_granted = true, bool show_dbg_info = true)
    {
        return fv->UpdateUsersInBulk(userIDs, ID_folders_path, is_delete_granted, show_dbg_info);

    }
    int RenameId(std::string old_id, std::string new_id)
    {
       return fv->RenameUserID(old_id, new_id);
    }

private:
    std::shared_ptr<FV> fv;
};

PYBIND11_MODULE(PythonManager_Pybind11, m) {
    py::class_<PyManager>(m, "Manager")
        .def(py::init<std::string, std::string, std::string, std::string, std::string, std::string, bool>())
        .def("add", &PyManager::AddUser)
        .def("remove", &PyManager::RemoveUser)
        .def("update", &PyManager::UpdateUser)
        .def("rename", &PyManager::RenameId)
        .def("update_in_bulk", &PyManager::UpdateUsersInBulk);
}

这就是我构建扩展的方式 (setup.py):


import os, sys
from os import environ, getcwd
from distutils.core import setup, Extension
from distutils import sysconfig
import getpass 
cpp_args = ['/std:c++17']

user = getpass.getuser()
sfc_module = Extension(
    'PythonManager_Pybind11', sources=['PythonManager_Pybind11.cpp', 'D:/cpp/port/LibtorchPort/Dependencies/include/messages/Config.pb.cc'],

    include_dirs=['pybind11/include',
                  f'C:/Users/{user}/Anaconda3/include',
                  f'C:/Users/{user}/Anaconda3/include/pybind11/',
                  "D:/External Libs/Opencv3.4.10_vc14_vc15/opencv3.4/include",
                  "D:/cpp/port/LibtorchPort/Dependencies/include",
                  "D:/cpp/port/LibtorchPort/Dependencies/libtorch-release-latest/libtorch/include",
                  "D:/cpp/port/LibtorchPort/Dependencies/libtorch-release-latest/libtorch/include/torch/csrc/api/include",
                  f'C:/Users/{user}/Anaconda3/Library/include',
                  f'C:/Users/{user}/Anaconda3/Lib/site-packages/numpy/core/include'],

    library_dirs=[# python3.6.7: f'C:/Users/{user}/Anaconda3/pkgs/openblas-0.3.3-h535eed3_1001/Library/lib',
                  "D:/cpp/port/LibtorchPort/x64/Release",
                  "D:/External Libs/Opencv3.4.10_vc14_vc15/opencv3.4/x64/vc14/lib",
                  "D:/cpp/port/LibtorchPort/Dependencies/libtorch-release-latest/libtorch/lib",
                  f'C:/Users/{user}/Anaconda3/libs',
                  f'C:/Users/{user}/Anaconda3'],

    libraries=['FV', 'libprotobuf-lite','libprotobuf','libprotoc','c10','asmjit','clog','cpuinfo','dnnl','fbgemm','mkldnn','torch','torch_cpu'],
    language='c++',
    extra_compile_args=cpp_args,
    )

setup(
    name='PythonManager_Pybind11',
    version='1.0',
    description='Python package with PythonExtension C++ extension (PyBind11)',
    ext_modules=[sfc_module],
)

现在做一个:
pip wheel .pip install -e . 构建扩展就好了。