无法跨DLL导出高兴的符号

时间:2019-09-12 14:29:19

标签: c++ c cmake linker-errors extern

我正在使用几个对象来编译动态库,其中一个对象是使用glad.h/.c编译的。我想公开extern变量(gl函数指针),以防gl_traits库(对象)将被编译成一些包含dll的文件。

gl_traits.h

#pragma once

#ifdef GL_TRAITS_BUILD
#define GLT_API __declspec(dllexport)
#define GLAD_GLAPI_EXPORT_BUILD
#else
#define GLT_API __declspec(dllimport)
#endif

#define GLAD_GLAPI_EXPORT
#include "glad.h"

shader_traits.cpp

#define GL_TRAITS_BUILD
#include "gl_traits.h"

但是,当我链接到包含的dll并尝试引用任何导出的(据说)gl函数指针(例如auto ptr = &glGenBuffers时,会得到无法解析的外部符号。

1>sandboxGL.cpp
1>sandboxGL.obj : error LNK2001: unresolved external symbol __imp_glad_glGenBuffers
1>C:\dev_build\test_exportGLAD\sandboxDLL\bin\Debug\sandboxGL.exe : fatal error LNK1120: 1 unresolved externals

我添加了另一个虚拟对象(ObjectLib),该对象导出了一个函数指针,并且确实很好(该函数已通过外部指针正确地调用了)。

ObjecLib.h

#pragma once

#ifdef BUILD_DLL
#define API __declspec(dllexport) extern
#else 
#define API __declspec(dllimport) extern
#endif // !BUILD_DLL


API int FromObject();

using PFuncInt = int(*)();

API PFuncInt ppObject;

ObjectLib.cpp

#define BUILD_DLL
#include "ObjectLib.h"

API int FromObject()
{
    return 16;
}


int Return48()
{
    return 1516;
}

PFuncInt ppObject = &Return48;

我正在使用CMake生成项目。 gl_traits对象(以及类似的ObjectLib):

add_library(gl_traits
    OBJECT
        include/gl_traits.h
        include/glad.h
        src/glad/glad.c

        src/shader_traits.cpp
    )

find_package(OpenGL REQUIRED)
message(STATUS "OpenGL libs: ${OPENGL_LIBRARIES}")

target_include_directories(gl_traits
    PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/include
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
    )

target_link_libraries(gl_traits
    PRIVATE
        ${OPENGL_LIBRARIES}
    )

用于构建共享库的Cmake文件,该文件必须包含其他对象gl_traits

add_library(sandboxDLL
    SHARED
        $<TARGET_OBJECTS:gl_traits>
        $<TARGET_OBJECTS:ObjectLib>
    )

target_link_libraries(sandboxDLL
    PUBLIC
        gl_traits
        ObjectLib
    )

add_executable(sandboxGL
    sandboxGL.cpp
    )

target_link_libraries(sandboxGL
    PRIVATE
        sandboxDLL
    )

sandboxGL.cpp

#include "sbDLL.h"
#include "gl_traits.h"

#include "ObjectLib.h"
#include <iostream>


int main()
{
    int a1 = a;

    auto ptr = &glGenBuffers;
    auto pptr = &exportedHello;

    //extern pointer from ObjectLib
    std::cout << ppObject() << std::endl;

    //extern function, defined in shader_traits.cpp
    exportedHello();

    return 0;
}

您可以从git克隆此项目: HTTP SSH

链接器无法解析从glad导出的符号的原因是什么?


更新

如果我使用glad.h/.ctarget_compile_definitions(glad_obj PRIVATE GLAD_GLAPI_EXPORT GLAD_GLAPI_EXPORT_BUILD)编译到单独的共享库中,则所有链接都可以正常运行。但是为什么不编译为对象呢?

UPDATE2

我已经使用glad_objtarget_compile_definitions(glad_obj PRIVATE GLAD_GLAPI_EXPORT GLAD_GLAPI_EXPORT_BUILD)构建为对象。然后,我还将gl_traits作为对象构建并将其与glad_obj链接。 下一步是SHARED dll,它将吸收这3个对象(包括虚拟ObjectLib),该对象与最终的可执行文件链接,并且一切正常。

因此,未知的部分是为什么在定义#define GLAD_GLAPI_EXPORT_BUILD宏时链接失败而没有通过cmake命令显式添加宏的原因? 尽管目前这种解决方法已经足够,但我需要gl_traitsglad成为一个库。

0 个答案:

没有答案