バックグラウンド:
C を学習する方法として、ゼルダ (NES) に似た単純なゲームを C で開発しようとしています。すべてのゲーム データを 1 つのファイルに格納するのは理想的ではないという結論に達しました。そこで私がやりたいのは、各「領域」を独自のモジュールに分割することです。この「エリア」モジュールは、タイル マップ、特定のイベントでトリガーする関数などのプロパティをメイン プログラムに記述し、メイン プログラムのゲーム API を呼び出してアクター/サウンド/その他を操作します。画面上。したがって、これらのモジュールは実行時にロード/アンロードする必要があります。本質的に、メイン プログラムは、この「エリア」モジュールから供給されるデータに基づいて動作するステート マシンです。
これらの共有モジュールを作成しようとしましたが、メイン プログラムで定義された関数が area モジュールから見えるようには見えません (少なくとも同じスコープではありません)。これは、リンクを間違っているためだと確信しています。だから私がやったことは、うまくいく概念の証明を考え出すことです. 以下は、失敗した私の概念実証です。
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 呼び出しを area モジュールに登録するという別のアイデアがあります... しかし、それは私にとって理想的ではありません。
マシン情報: gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3.