简体   繁体   中英

C++ forward declare inline function in namespace problem

I'm trying forward declare my functions in a namespace. But I get an error. Let me show my.h and.cpp files first.

Header:

namespace DeviceList
{
     int GetIDFromType(NNBSSString type);
     NNBSSString GetTypeFromID(int id);
     void CNNBSSDeviceListAddDevice(NNBSSString& DeviceName, NNBSSString& Address, int DeviceType,
        __STRING__ DeviceNetName, __STRING__ DevicePath);
     void CNNBSSDeviceListRemoveSelected();
     void CNNBSSDeviceListRemoveCache(int index);
     inline void CNNBSSDeviceListAddressConnectionRespond(NNBSSString& deviceAddress, bool OK, NNBSSThread* thread);
     void CNNBSSDeviceListUpdate();
}

And Source file:

namespace DeviceList
{
    int GetIDFromType(NNBSSString type)
    {
        int m_id;

        if (type == _("USB Camera"))
        {
            m_id = NNBSS_EVT_DEVICETYPE_USBCAM;
        }
        else if (type == _("IP Camera"))
        {
            m_id = NNBSS_EVT_DEVICETYPE_IPCAM;
        }
        else if (type == _("Microphone"))
        {
            m_id = NNBSS_EVT_DEVICETYPE_MICROPHONE;
        }
        else if (type == _("DVR"))
        {
            m_id = NNBSS_EVT_DEVICETYPE_DVR;
        }
        else if (type == _("NVR"))
        {
            m_id = NNBSS_EVT_DEVICETYPE_NVR;
        }
        else
        {
            m_id = -100;
            NNBSSErrorShow("Given DeviceType was wrong while getting int from NNBSSString!", 100);
        }

        return m_id;
    }

    NNBSSString GetTypeFromID(int id)
    {
        // Has to be given by using GetIDFromEnum

        NNBSSString m_type;

        switch (id)
        {
        case NNBSS_EVT_DEVICETYPE_USBCAM:
            m_type = _("USB Camera");
            break;
        case NNBSS_EVT_DEVICETYPE_IPCAM:
            m_type = _("IP Camera");
            break;
        case NNBSS_EVT_DEVICETYPE_MICROPHONE:
            m_type = _("Microphone");
            break;
        case NNBSS_EVT_DEVICETYPE_DVR:
            m_type = _("DVR");
            break;
        case NNBSS_EVT_DEVICETYPE_NVR:
            m_type = _("NVR");
            break;
        default:
            NNBSSErrorShow("Given DeviceType was wrong while getting NNBSSString from int!", 100);
            break;
        }

        return m_type;
    }

    void CNNBSSDeviceListAddDevice(NNBSSString& DeviceName, NNBSSString& Address, int DeviceType,
        __STRING__ DeviceNetName = __STRING__(), __STRING__ DevicePath = __STRING__())
    {
        SCNNBSSDeviceParameters params;
        params.DeviceName = DeviceName;
        params.Address = Address;
        params.DeviceType = DeviceType;
        params.DeviceNetName = DeviceNetName;
        params.DevicePath = DevicePath;

        SCNNBSSDeviceParametersList.emplace_back(params);

        {
            CNNBSSHardwareCheckCameraConnection* p_CNNBSSHardwareCheckCameraConnection =
                new CNNBSSHardwareCheckCameraConnection(Address);
            p_CNNBSSHardwareCheckCameraConnection->Run();
        }

        // Update all pages that have Device List active
        for (int c = 0; c < (int)m_NNBSSContentPanelList.size(); c++)
        {
            int pageID = c - 1;
            pageID < 0 ? pageID = 0 : pageID = c - 1;

            if (CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_IsCreated)
            {
                CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_RecreateList();
            }
        }
    }

    void CNNBSSDeviceListRemoveSelected()
    {
        if (CNNBSSDeviceListAddressHandle(CNNBSSControlPanelAddressHandle()->_GetCurrentContentPanel())->_IsCreated)
        {
            CNNBSSDeviceListAddressHandle(CNNBSSControlPanelAddressHandle()->_GetCurrentContentPanel())
                ->_RemoveSelectedFromList();
        }

        // Update all pages that have Device List active
        for (int c = 0; c < (int)m_NNBSSContentPanelList.size(); c++) {
            int pageID = c - 1;
            pageID < 0 ? pageID = 0 : pageID = c - 1;

            if (CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_IsCreated)
            {
                CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_RecreateList();
            }
        }
    }

    void CNNBSSDeviceListRemoveCache(int index)
    {
        if (index < 0)
        {
            index = 0;
        }

        if (SCNNBSSDeviceParametersList.size() < index)
        {
            index = (int)SCNNBSSDeviceParametersList.size();
        }

        auto itr = SCNNBSSDeviceParametersList.begin();
        std::advance(itr, index);

        if (itr != SCNNBSSDeviceParametersList.end())
        {
            SCNNBSSDeviceParametersList.erase(itr);
        }
    }

    void CNNBSSDeviceListAddressConnectionRespond(NNBSSString& deviceAddress, bool OK, wxThread* thread)
    {
        for (int c = 0; c < (int)SCNNBSSDeviceParametersList.size(); c++)
        {
            if (SCNNBSSDeviceParametersList[c].Address == deviceAddress)
            {
                if (OK)
                {
                    SCNNBSSDeviceParametersList[c].DeviceConnectionStatus = NNBSS_DEVICE_CONNECTION_STATUS_STRING_ONLINE;
                }
                else
                {
                    SCNNBSSDeviceParametersList[c].DeviceConnectionStatus = NNBSS_DEVICE_CONNECTION_STATUS_STRING_UNKNOWNERROR;
                }

                break;
            }
        }

        // Update all pages that have Device List active
        for (int c = 0; c < (int)m_NNBSSContentPanelList.size(); c++)
        {
            int pageID = c - 1;
            pageID < 0 ? pageID = 0 : pageID = c - 1;

            if (CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_IsCreated)
            {
                CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_RecreateList();
            }
        }

        // Delete thread
        thread->Delete();
        delete thread;
    }

    void CNNBSSDeviceListUpdate()
    {// Whenever a USB device is connected, this function will be called automatically
        {
            std::vector<__STRING__> currentDevices, currentDevicePaths;
            CNNBSSHardwareAddressHandle()->GetConnectedUSBCameraList(currentDevices, currentDevicePaths);
            
        // Update all pages that have Device List active
        for (int c = 0; c < (int)m_NNBSSContentPanelList.size(); c++)
        {
            int pageID = c - 1;
            pageID < 0 ? pageID = 0 : pageID = c - 1;

            if (CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_IsCreated)
            {
                CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_RecreateList();
            }
        }
    }
}

The problem is, when I remove inline keyword before CNNBSSDeviceListAddressConnectionRespond function, compiler throws an error though for others compiler does not do the same. I wonder, why others works without inline but not CNNBSSDeviceListAddressConnectionRespond function?

Additionally, the complete error message:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK1169 one or more multiply defined symbols found  NNBSS   NNBSS\Build\Debug\NNBSS.exe 1   
Error   LNK2005 "void __cdecl DeviceList::CNNBSSDeviceListAddressConnectionRespond(class NNBSSString &,bool,class NNBSSThread *)" (?CNNBSSDeviceListAddressConnectionRespond@DeviceList@@YAXAEAVNNBSSString@@_NPEAVNNBSSThread@@@Z) already defined in ClassManager.obj NNBSS   NNBSS\Build\Thread.obj  1   

I use include guards. And my header file is included by over 128 files.

If anything's missing here, let me know

It seems you are using VS2019. I had the same problem and as inte.net says we're not alone. So, it's a bug that will be fixed once you rebuild the project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM