gpt4 book ai didi

C共享库问题

转载 作者:太空宇宙 更新时间:2023-11-04 01:42:07 28 4
gpt4 key购买 nike

背景:

我正在尝试用 C 开发一个类似于 Zelda (NES) 的简单游戏,作为学习 C 的一种方式。我得出的结论是将所有游戏数据放在一个文件中并不理想。所以我想做的是将每个“区域”分解成它自己的模块。这个“区域”模块将向主程序描述它的属性,例如瓦片 map 、触发特定事件的函数,以及调用主程序的游戏 API 来操作 Actor /声音/等。屏幕上。因此,这些模块必须在运行时加载/卸载。本质上,主程序是一个状态机,它处理从这个“区域”模块提供给它的任何数据。

我已经尝试创建这些共享模块,但似乎主程序中定义的函数对区域模块不可见(至少不在同一范围内)。我确定这是因为我链接不正确。所以我所做的是尝试提出一个可行的概念证明。以下是我失败的概念证明:

api.h

#ifndef _API_H
#define _API_H

static char *name = 0;

extern int play_sfx(int, int, int);
extern int move_actor(int, int, int);
extern int set_name(char*);
extern char* get_name(void);

#endif

区域.c

#include "api.h"

extern int init(void)
{
int ret = set_name("area 1");
return ret;
}

game.c

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

#include "api.h"

int main()
{
void *handle = dlopen("/home/eric/tmp/build_shared5/libarea.so", RTLD_LAZY);
int (*test)(void) = dlsym(handle, "init");
(*test)();
dlclose(handle);
printf("Name: %s\n", get_name());
return 0;
}

extern int play_sfx(int id, int times, int volume)
{
// @todo Execute API call to play sfx
return 1;
}

extern int move_actor(int id, int x, int y)
{
// @todo Execute API call to move actor
return 1;
}

extern int set_name(char *p)
{
name = p;

return 1;
}

extern char* get_name(void)
{
return name;
}

build.sh

#!/bin/bash
gcc -o game.o -c game.c
gcc -fPIC -o area.o -c area.c
#,--no-undefined
gcc -shared -Wl,-soname,libarea.so.1 -o libarea.so game.o area.o
gcc -o game game.o -ldl

构建:

$./build.sh

程序产生:

$./游戏

姓名:(空)

我希望看到:名称:区域 1

我正在尝试做的事情是否可行?如果没有,我有另一个想法,就是将所有 API 调用注册到区域模块……但对我来说,这是理想的。

机器信息:gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3。

最佳答案

您的 .h 文件中有 static char *name = 0;,这会引起混淆。

您的 area.c 包含 app.h 并将获得一个 char *name 仅在其翻译单元中可见,因为它是静态的。

您的 game.c 还包含 app.h 并将获得另一个 char *name 变量。因此 area.c 看到的 name 与 game.c 看到的不一样,并且在它们各自的 .c 文件之外都不可见。您可以在共享库和主要可执行文件上运行 nm 来验证这一点。两者都应该有一个 provate name symbol

extern char *name; 放在 app.h 中而不是 static char *name; 并将 char *name; 放在文件的某处game.c 中的作用域

(虽然我有点不确定在使用动态加载共享库时是否会正确解析)。

关于C共享库问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3773196/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com