Отредактировано: Исправлено 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.