C ++ Shared Lib: в Windows клиентская ссылка в порядке, но в Linux (GCC) возникают неопределенные ошибки - PullRequest
0 голосов
/ 18 мая 2019

Отредактировано: Исправлено ODR исправлено.

Отредактировано: Я обнаружил, что переупорядочение каталогов ссылок (-L) решило проблему, ноЯ не знаю почему.

Исходный порядок в команде g ++, который вызывал проблему, был следующим:

-L/usr/local/lib
-L/usr/local/lib64
-L/usr/lib
-L/usr/lib/64
-L../../bin/Release

Перемещение -L../../bin/Release, содержащее VampEngine.so, решило проблему, но почему? Edited Ends Here

У меня есть два проекта. VampEngine (общая библиотека) и Приложение (клиент).Когда я компилирую их в Windows (Visual C ++), VampEngine прекрасно связывается с Приложением, но в Linux я получаю неопределенных ошибок (g ++) .

Iпроверил, переданы ли правильные флаги и пути в аргументах компилятора, и это кажется правильным.Также я весьма уверен, что использую extern "C" как в реализации dll, так и в замедлениях клиента.

Вот аналитическое выполнение make-файла g ++:


-------------- Clean: Debug|x64 in VampEngine (compiler: GNU GCC Compiler)---------------

Cleaned "VampEngine - Debug|x64"

-------------- Clean: Debug|x64 in Application (compiler: GNU GCC Compiler)---------------

Cleaned "Application - Debug|x64"

-------------- Build: Debug|x64 in VampEngine (compiler: GNU GCC Compiler)---------------

g++ -m64 -fPIC -I../../Depedencies/Cross-Plat/glm-0.9.9.5 -I/usr/include -I/usr/local/include -c /home/babaliaris/Deve/cpp/VampEngine/VampEngine/src/core.cpp -o ../../bin-int/Debug/VampEngine/x64/Debug/VampEngine/VampEngine/src/core.o
g++ -m64 -fPIC -I../../Depedencies/Cross-Plat/glm-0.9.9.5 -I/usr/include -I/usr/local/include -c /home/babaliaris/Deve/cpp/VampEngine/VampEngine/src/stb_image/stb_image.cpp -o ../../bin-int/Debug/VampEngine/x64/Debug/VampEngine/VampEngine/src/stb_image/stb_image.o
g++ -m64 -fPIC -I../../Depedencies/Cross-Plat/glm-0.9.9.5 -I/usr/include -I/usr/local/include -c /home/babaliaris/Deve/cpp/VampEngine/VampEngine/src/window.cpp -o ../../bin-int/Debug/VampEngine/x64/Debug/VampEngine/VampEngine/src/window.o
g++ -shared -L/usr/lib -L/usr/lib64 -L/usr/local/lib -L/usr/local/lib64 ../../bin-int/Debug/VampEngine/x64/Debug/VampEngine/VampEngine/src/core.o ../../bin-int/Debug/VampEngine/x64/Debug/VampEngine/VampEngine/src/stb_image/stb_image.o ../../bin-int/Debug/VampEngine/x64/Debug/VampEngine/VampEngine/src/window.o  -o ../../bin/Debug/libVampEngine.so -s -shared -m64 -L/usr/lib64  -lGL -lGLEW -lglfw
Output file is ../../bin/Debug/libVampEngine.so with size 138.57 KB

-------------- Build: Debug|x64 in Application (compiler: GNU GCC Compiler)---------------

g++ -m64 -I../../Depedencies/Cross-Plat/glm-0.9.9.5 -I../../VampEngine/src -I/usr/include -I/usr/local/include -c /home/babaliaris/Deve/cpp/VampEngine/Application/src/main.cpp -o ../../bin-int/Debug/VampEngine/x64/Debug/Application/Application/src/main.o
g++ -L/usr/lib -L/usr/lib64 -L/usr/local/lib -L/usr/local/lib64 -L../../bin/Debug -o ../../bin/Debug/Application ../../bin-int/Debug/VampEngine/x64/Debug/Application/Application/src/main.o  -s -m64 -L/usr/lib64  -lVampEngine
/usr/bin/ld: ../../bin-int/Debug/VampEngine/x64/Debug/Application/Application/src/main.o: in function `VampEngine::Core::Core(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int, unsigned int)':
main.cpp:(.text._ZN10VampEngine4CoreC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjj[_ZN10VampEngine4CoreC5ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjj]+0x31): undefined reference to `Vamp_Core_Constructor'
/usr/bin/ld: ../../bin-int/Debug/VampEngine/x64/Debug/Application/Application/src/main.o: in function `VampEngine::Core::~Core()':
main.cpp:(.text._ZN10VampEngine4CoreD2Ev[_ZN10VampEngine4CoreD5Ev]+0x17): undefined reference to `Vamp_Core_Deconstructor'
/usr/bin/ld: ../../bin-int/Debug/VampEngine/x64/Debug/Application/Application/src/main.o: in function `VampEngine::Core::MainLoop()':
main.cpp:(.text._ZN10VampEngine4Core8MainLoopEv[_ZN10VampEngine4Core8MainLoopEv]+0x17): undefined reference to `Vamp_Core_MainLoop'
collect2: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 1 second(s))
4 error(s), 0 warning(s) (0 minute(s), 1 second(s))

ВотФайл core.cpp, который содержит реализацию функций extern в общей библиотеке:

#include "core.h"
#include "window.h"
#include <GLFW/glfw3.h>
#include "Engine/API.h"

namespace VampEngine
{

    CoreImpl::CoreImpl(std::string title, unsigned int width, unsigned int height)
        : window( new WindowImpl(title, width, height) )
    {
    }


    CoreImpl::~CoreImpl()
    {
        delete window;
    }

    void CoreImpl::MainLoop()
    {
        /* Loop until the user closes the window */
        while (!glfwWindowShouldClose(window->m_window))
        {
            /* Render here */
            glClear(GL_COLOR_BUFFER_BIT);

            /* Swap front and back buffers */
            glfwSwapBuffers(window->m_window);

            /* Poll for and process events */
            glfwPollEvents();
        }
    }
}


extern "C" VAMP_API void* Vamp_Core_Constructor(const char* title, unsigned int width, unsigned int height)
{
    return new VampEngine::CoreImpl(title, width, height);
}




extern "C" VAMP_API void Vamp_Core_Deconstructor(void* obj)
{
    VampEngine::CoreImpl *object = (VampEngine::CoreImpl*)obj;
    delete object;
}




extern "C" VAMP_API void Vamp_Core_MainLoop(void* obj)
{
    VampEngine::CoreImpl* object = (VampEngine::CoreImpl*)obj;
    object->MainLoop();
}

А это файл core.hpp, который клиент включает и компилирует в своем файле main.cpp:

#ifndef VAMP_ENGINE_CORE_HPP
#define VAMP_ENGINE_CORE_HPP
#include <Engine/API.h>
#include <iostream>

extern "C"
{
    VAMP_API void* Vamp_Core_Constructor(const char* title, unsigned int width, unsigned int height);
    VAMP_API void Vamp_Core_Deconstructor(void* obj);
    VAMP_API void Vamp_Core_MainLoop(void* obj);
}

namespace VampEngine
{
    class Core
    {

    private:
        void* m_core;

    public:
        Core(std::string title, unsigned int width, unsigned int height)
            : m_core(Vamp_Core_Constructor(title.c_str(), width, height))
        {
        }

        ~Core()
        {
            Vamp_Core_Deconstructor(m_core);
        }

        void MainLoop()
        {
            Vamp_Core_MainLoop(m_core);
        }
    };
}

#endif

Макрос VAMP_API пуст при компиляции в Linux.

#ifndef VAMP_ENGINE_API_H
#define VAMP_ENGINE_API_H

//On Windows Platforms.
#ifdef VAMP_PLATFORM_WINDOWS
    #ifdef VAMP_BUILD_DLL
        #define VAMP_API _declspec(dllexport)
    #else
        #define VAMP_API _declspec(dllimport)
    #endif

//Unix-Based Systems (GCC).
#else
    #define VAMP_API
#endif

#endif

Как видите, я использую точно такие же имена.

Так что еще может вызвать неопределенную ошибку?

Я использую arch linux x64, с версией gcc:

$gcc --version
gcc (GCC) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

1 Ответ

0 голосов
/ 19 мая 2019

Проблема решена.

Мой код был просто в порядке, виновником была фактически другая библиотека libVampEngine.so , которая была скопирована мной в / usr / lib . Компоновщик сначала искал в каталоге / usr / lib , а затем в каталоге bin / моего проекта, поэтому вместо использования правильного файла .so для ссылки он использовал устаревший.

Если кто-то еще испытывает проблему, подобную этой, и почти уверен, что его код в порядке, выполните следующие действия:

1) Ensure that the linker is actually linking the correct shared library.
2) Check the library directories (-L) that the linker is searching for binaries.
    -Make sure these directories do not contain a binary with the exact same name as 
     your own library.
3) Be carefull of outdated binary files. If the linker is linking against 
   one but your code has been updated, even if the program links correctly you will get
   undefined behavior on runtime. 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...