admin管理员组

文章数量:1122832

I know what LNK1169 stands for. So the point is not what this error is, but why it happens, especially since the duplicate defined function is a destructor of an stl template.

The full error is below:

datachannel.lib(datachannel.dll) : error LNK2005: "public: __cdecl std::vector<enum std::byte,class std::allocator<enum std::byte> >::~vector<enum std::byte,class std::allocator<enum std::byte> >(void)" (??1?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@QEAA@XZ) already defined in media_source.obj [D:\projects\conference-go-client\build\test-uvc.vcxproj]
[build] D:\projects\conference-go-client\build\Debug\test-uvc.exe : fatal error LNK1169: Find one or more symbols with multiple definitions 

In media_source.obj I could find code related to std::vector<std::byte> simplified as follows

// media_source.hpp
    using media_packet_t = std::vector<std::byte>;
    using media_packet_ptr_t = std::shared_ptr<media_packet_t>;
    class MediaReceiver
    {
    public:
        virtual ~MediaReceiver() = default;
        virtual auto request_pkt(close_chan closer) -> asio::awaitable<media_packet_ptr_t> = 0;
        virtual void request_key_frame() = 0;
    };

// media_source.cpp
    struct MediaReceiverImpl
    {
        MediaReceiverImpl(){}

        auto request_pkt(close_chan closer) -> asio::awaitable<media_packet_ptr_t>;
        void request_key_frame();
    };
    struct MediaReceiverWrapper : public MediaReceiver
    {
        using impl_t = unique_smart_node<MediaReceiverImpl>;
        unique_smart_node<MediaReceiverImpl> m_impl;

        MediaReceiverWrapper(impl_t && impl): m_impl(std::move(impl)) {}
        ~MediaReceiverWrapper() = default;
        auto request_pkt(close_chan closer) -> asio::awaitable<media_packet_ptr_t> override
        {
            return m_impl->request_pkt(std::move(closer));
        }
        void request_key_frame() override
        {
            m_impl->request_key_frame();
        }
    };

The std::vector<std::byte> used in libdatachannel should refer to the

namespace rtc {
   using std::byte;
   using binary = std::vector<byte>;
};

In addition, the above error only occurs on windows platform, not on linux with gcc.

Update:

After change my own defined media_packet_t to rtc::binary, the error disappeared. But I'm still trying to figure out why.

  // using media_packet_t = std::vector<std::byte>;
  // using media_packet_ptr_t = std::shared_ptr<media_packet_t>;
  using media_packet_t = rtc::binary;
  using media_packet_ptr_t = std::shared_ptr<media_packet_t>;

I know what LNK1169 stands for. So the point is not what this error is, but why it happens, especially since the duplicate defined function is a destructor of an stl template.

The full error is below:

datachannel.lib(datachannel.dll) : error LNK2005: "public: __cdecl std::vector<enum std::byte,class std::allocator<enum std::byte> >::~vector<enum std::byte,class std::allocator<enum std::byte> >(void)" (??1?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@QEAA@XZ) already defined in media_source.obj [D:\projects\conference-go-client\build\test-uvc.vcxproj]
[build] D:\projects\conference-go-client\build\Debug\test-uvc.exe : fatal error LNK1169: Find one or more symbols with multiple definitions 

In media_source.obj I could find code related to std::vector<std::byte> simplified as follows

// media_source.hpp
    using media_packet_t = std::vector<std::byte>;
    using media_packet_ptr_t = std::shared_ptr<media_packet_t>;
    class MediaReceiver
    {
    public:
        virtual ~MediaReceiver() = default;
        virtual auto request_pkt(close_chan closer) -> asio::awaitable<media_packet_ptr_t> = 0;
        virtual void request_key_frame() = 0;
    };

// media_source.cpp
    struct MediaReceiverImpl
    {
        MediaReceiverImpl(){}

        auto request_pkt(close_chan closer) -> asio::awaitable<media_packet_ptr_t>;
        void request_key_frame();
    };
    struct MediaReceiverWrapper : public MediaReceiver
    {
        using impl_t = unique_smart_node<MediaReceiverImpl>;
        unique_smart_node<MediaReceiverImpl> m_impl;

        MediaReceiverWrapper(impl_t && impl): m_impl(std::move(impl)) {}
        ~MediaReceiverWrapper() = default;
        auto request_pkt(close_chan closer) -> asio::awaitable<media_packet_ptr_t> override
        {
            return m_impl->request_pkt(std::move(closer));
        }
        void request_key_frame() override
        {
            m_impl->request_key_frame();
        }
    };

The std::vector<std::byte> used in libdatachannel should refer to the

namespace rtc {
   using std::byte;
   using binary = std::vector<byte>;
};

In addition, the above error only occurs on windows platform, not on linux with gcc.

Update:

After change my own defined media_packet_t to rtc::binary, the error disappeared. But I'm still trying to figure out why.

  // using media_packet_t = std::vector<std::byte>;
  // using media_packet_ptr_t = std::shared_ptr<media_packet_t>;
  using media_packet_t = rtc::binary;
  using media_packet_ptr_t = std::shared_ptr<media_packet_t>;
Share Improve this question edited Nov 21, 2024 at 17:28 vipcxj asked Nov 21, 2024 at 16:35 vipcxjvipcxj 1,0387 silver badges11 bronze badges 8
  • OT: You very seldom need a pointer to a container. What problem is media_packet_ptr_t supposed to solve? – Some programmer dude Commented Nov 21, 2024 at 16:45
  • Are you using pre-compiled headers? – 3CxEZiVlQ Commented Nov 21, 2024 at 16:47
  • media_source is using std::vector<std::byte> but libdatachannel is using std::vector<byte>, is it possible that libdatachannel has redefined what byte is and is conflicting with the standard byte? – Remy Lebeau Commented Nov 21, 2024 at 16:49
  • To avoid copying, media_packet_ptr_t is likely to be shared, so move won't work, and it will end up being passed to libdatachannel, where the type of parameter that needs to be accepted is rtc::binnary = std::vector<byte>, but I don't want to introduce the whole rtc/rtc.h in media_sourc just because of this single type, so I'm typedef it again – vipcxj Commented Nov 21, 2024 at 16:49
  • 1 Using pre-compiled headers is likely a root issue. A minimal reproducible example should be posted so I can point to the issue. – 3CxEZiVlQ Commented Nov 21, 2024 at 17:03
 |  Show 3 more comments

1 Answer 1

Reset to default 0

I found the key is "rtc/track.hpp" in libdatachannel

class RTC_CPP_EXPORT Track final : private CheshireCat<impl::Track>, public Channel {
public:
    void onFrame(std::function<void(binary data, FrameInfo frame)> callback);
};

If I include this header, the issue disappeared. It seems that RTC_CPP_EXPORT is the key. it is __declspec(dllimport) on windows, but nothing on linux. So the issue only happen on windows.

I'm not sure exactly why yet, but it should have something to do with it

本文标签: cerror LNK1169 of stdvectorltstdbytegt destructorStack Overflow