Contexte:C partagée question bibliothèque
Je suis en train de développer un jeu simple similaire à Zelda (NES) en C comme un moyen d'apprendre C. Je suis venu à la conclusion que présentant toutes les caractéristiques jeu les données dans un seul fichier ne sont pas idéales. Donc, ce que je voudrais faire est de diviser chaque «zone» dans son propre module. Ce module "zone" décrira au programme principal ses propriétés, telles qu'une carte de tuiles, des fonctions à déclencher sur certains événements, et appellera l'API de jeu du programme principal pour manipuler les acteurs/sons/etc. sur l'écran. Ainsi, ces modules doivent être chargés/déchargés au moment de l'exécution. Essentiellement, le programme principal est une machine d'état qui fonctionne à partir de toutes les données qui lui sont fournies à partir de ce module "zone".
J'ai essayé de créer ces modules partagés mais il ne semble pas que les fonctions définies dans le programme principal soient visibles par le module de zone (du moins pas dans le même cadre). Je suis sûr que c'est parce que je le relie incorrectement. Donc ce que j'ai fait est d'essayer de trouver une preuve de concept qui fonctionnerait. Ci-dessous mon, à défaut, la preuve de concept:
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
area.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
Construire:
./build.sh $
Le programme produit:
./game $
Nom: (null)
Je m'attendais à voir: Nom: zone 1
Est-ce que ce que j'essaie de faire est même possible? Sinon, j'ai une autre idée qui consiste à enregistrer tous les appels d'API au module de zone ... mais pour moi, c'est pas idéal.
Informations sur la machine: gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3.
ressemble à la LUA-Language –
Je suis assez sûr que Zelda sur le NES n'a pas besoin de chargement/déchargement des bibliothèques dynamiques à l'exécution. :) – bk1e