Получение ошибки компоновщика LNK2001: неразрешенный внешний символ PyInit_your_module_name при создании расширения Python с использованием Pybind11

#python #c #pybind11

#python #c #pybind11

Вопрос:

Я пытаюсь создать расширение Python, используя Pybind11, и я полагаю, что правильно настроил все библиотеки, объекты, связанные с компоновщиком. Однако я получаю эту странную ошибку компоновщика! Это мой пример ввода

 #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", amp;PyManager::AddUser)
        .def("remove", amp;PyManager::RemoveUser)
        .def("update", amp;PyManager::UpdateUser)
        .def("rename", amp;PyManager::RenameId)
        .def("update_in_bulk", amp;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:UsersUserAppDataLocalTemppip-req-build-xl1k7s1fbuildlib.win-amd64-3.7
    C:Program Files (x86)Microsoft Visual Studio2019EnterpriseVCToolsMSVC14.27.29110binHostX86x64link.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:UsersUserAnaconda3libs /LIBPATH:C:UsersUserAnaconda3PCbuildamd64 "/LIBPATH:C:Program Files (x86)Microsoft Visual Studio2019EnterpriseVCToolsMSVC14.27.29110ATLMFClibx64" "/LIBPATH:C:Program Files (x86)Microsoft Visual Studio2019EnterpriseVCToolsMSVC14.27.29110libx64" "/LIBPATH:C:Program Files (x86)Windows KitsNETFXSDK4.8libumx64" "/LIBPATH:C:Program Files (x86)Windows Kits10lib10.0.18362.0ucrtx64" "/LIBPATH:C:Program Files (x86)Windows Kits10lib10.0.18362.0umx64" 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 buildtemp.win-amd64-3.7ReleasePythonManager_Pybind11.obj buildtemp.win-amd64-3.7ReleaseCodes/fac_ver/cpp/port/LibtorchPort/Dependencies/include/messages/Config.pb.obj /OUT:buildlib.win-amd64-3.7PythonManager_Pybind11.cp37-win_amd64.pyd /IMPLIB:buildtemp.win-amd64-3.7ReleasePythonManager_Pybind11.cp37-win_amd64.lib
    LINK : error LNK2001: unresolved external symbol PyInit_PythonManager_Pybind11
    buildtemp.win-amd64-3.7ReleasePythonManager_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
  

Чего мне здесь не хватает?

Ответ №1:

Хорошо, я допустил глупую ошибку! кажется, что при определении 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", amp;PyManager::AddUser)
        .def("remove", amp;PyManager::RemoveUser)
        .def("update", amp;PyManager::UpdateUser)
        .def("rename", amp;PyManager::RenameId)
        .def("update_in_bulk", amp;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 . создает расширение просто отлично.