You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

游戏引擎开发:无对应头文件时如何引用SO文件?

没有头文件时引用SO共享对象的方法

嘿,我懂你的处境——你已经把游戏引擎依赖的中间件编译成SO文件了,但现在手头没有对应的头文件,想知道怎么在代码里调用这些库的功能对吧?下面给你两种实用的解决方案,根据你的场景选就行:


方法一:手动声明需要的符号(适合知道API原型的情况)

如果你清楚要调用的库函数、结构体的原型(比如GLFW的glfwInit()、glfwCreateWindow这些公开API),你可以自己手动写一个简易的头文件,把需要用到的符号都声明出来。

举个GLFW的例子,你可以创建一个my_glfw.h:

// 手动声明GLFW的基础类型和函数
typedef void* GLFWwindow;

int glfwInit(void);
void glfwTerminate(void);
GLFWwindow* glfwCreateWindow(int width, int height, const char* title, void* monitor, GLFWwindow* share);
void glfwWindowShouldClose(GLFWwindow* window);
void glfwSwapBuffers(GLFWwindow* window);
// 其他你需要用到的函数/类型声明

然后在你的代码里直接包含这个头文件,CMake里还是保持你原来的导入库链接逻辑就行:

add_library (glfw SHARED IMPORTED)
set_target_properties (glfw PROPERTIES IMPORTED_LOCATION ${ENGINE_BINARIES_DIR}/Libraries/Shared/libglfw.so.3.2 )
target_link_libraries(your_engine_executable PRIVATE glfw)

⚠️ 注意:这种方法一定要保证你的声明和SO文件里的实际符号完全匹配(包括返回值、参数类型、调用约定),一旦写错,运行时很容易崩溃或者出现未定义行为。如果能找到对应版本的官方头文件,优先用官方的,别自己瞎写!


方法二:动态加载SO文件(灵活,无需提前链接)

如果你不想手动声明一堆符号,或者不确定要用到哪些函数,可以用POSIX标准的动态链接函数(dlopen、dlsym)在运行时加载SO并获取函数地址。

示例代码如下:

#include <dlfcn.h>
#include <stdio.h>

int main() {
    // 加载目标SO文件
    void* lib_handle = dlopen("${ENGINE_BINARIES_DIR}/Libraries/Shared/libglfw.so.3.2", RTLD_LAZY);
    if (!lib_handle) {
        fprintf(stderr, "Failed to load GLFW: %s\n", dlerror());
        return 1;
    }

    // 定义函数指针类型,然后获取函数地址
    typedef int (*GlfwInitFunc)(void);
    GlfwInitFunc glfw_init = (GlfwInitFunc)dlsym(lib_handle, "glfwInit");
    if (!glfw_init) {
        fprintf(stderr, "Failed to get glfwInit: %s\n", dlerror());
        dlclose(lib_handle);
        return 1;
    }

    // 调用函数
    if (glfw_init()) {
        // 同理,获取其他需要的函数地址
        typedef void (*GlfwTerminateFunc)(void);
        GlfwTerminateFunc glfw_terminate = (GlfwTerminateFunc)dlsym(lib_handle, "glfwTerminate");
        if (glfw_terminate) {
            glfw_terminate();
        }
    }

    // 用完记得关闭库句柄
    dlclose(lib_handle);
    return 0;
}

编译的时候,需要链接dl库,在CMake里加上:

target_link_libraries(your_engine_executable PRIVATE dl)

这种方法的好处是:不需要提前链接库,运行时才加载;也不用写一堆头文件声明。但缺点是每次调用函数都要先获取地址,代码会稍微繁琐一点。


额外提醒

  1. 如果是C编写的SO库,要注意名字修饰(name mangling)——C会把函数名改成带参数信息的奇怪字符串,这时候你要么知道修饰后的符号名,要么确保库是用extern "C"导出的符号(像GLFW这种C库就没这个问题)。
  2. 最稳妥的办法还是尽量找到对应版本的官方头文件,手动声明太容易踩坑了!

内容的提问来源于stack exchange,提问作者StickyFingies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:17:52