0

I was assigned to edit part of Ansi C application but my knowledge of pure C is just basics. Anyway current situation is I have map1_data1.h, map1_data2.h, map2_data1.h, map2_data2.h and variables in those files are always connected to the map name = map1_structure in map1_data1.h and so on.

In app there is #include for each file and in code then something like

if (game->map == 1){
    mapStructure = map1_structure
} else {
    mapStructure = map2_structure
}

I have to extend this to be able to load the map dynamicly so something like

void loadMap(int mapId){
    mapStructure = map*mapId*_structure // just short for what i want to achieve
}

My first idea to do so was removing map name connection in variables name in map1_data.h and have just structure variable in there. That requires only one header file at time to be loaded and thats where I'm stucked. Havent found any clues to do so on google.

I would like to have it as variable as possible so something like #include "map*mapId*_data1.h" but should be ok to have 1 switch in one place in whole app to decide on what map to be loaded.

One more thing, the app keeps running for more than 1 game = it will load various maps in one run.

4

1 回答 1

0

Judging from the comments, you have a single type, call it Map, which is a structure type containing a collection of different data types, including 3D arrays and points and so on. You need to have some maps built into the program; later on, you will need to load new maps at runtime.

You have two main options for the runtime loading the maps:

  1. Map in shared object (shared library, dynamically loaded library, aka DLL).
  2. Map in data file.

Of these two, you will choose the data file over the shared object because it is, ultimately, simpler and more flexible.

Shared Object

With option 1, only someone who can compile a shared library can create the new maps. You'd have a 'library' consisting of one or more data objects, which can be looked up by name. On most Unix-like systems, you'd end up using dlopen() to load the library, and then dlsym() to find the symbol name in that library (specifying the name via a string). If it is present in the library, dlsym() will return you a pointer.

In outline:

typedef void *SO_Handle;
const char *path_to_library = "/usr/local/lib/your_game/libmap32.so";
const char *symbol_name     = "map32_structure";

SO_Handle lib = dlopen(path_to_library, RTLD_NOW);
if (lib == 0)
    ...bail out...
map_structure = dlsym(lib, symbol_name);
if (map_structure == 0)
    ...bail out...

You have to have some way of generating the library name based on where the software is installed and where extensions are downloaded. You also have to have some way of knowing the name of the symbol to look for. The simplest system is to use a single fixed name (map_structure), but you are not constrained to do that.

After this, you have your general map_structure read for use. You can invent endless variations on the theme.

Data file

This is the more likely way you'll do it. You arrange to serialize the map structure into a disk file that can be read by your program. This will contain a convenient representation of the data. You should consider the TLV (type-length-value) encoding scheme, so that you can tell by looking at the type what sort of data follows, and the length tells you how many of them, and the value is the data. You can do this with binary data or with text data. It is easier to debug text data because you can look at and see what's going on. The chances are that the difference in performance between binary and text is small enough (swamped by the I/O time) that using text is the correct way to go.

With a text description of the map, you'd have information to identify the file as being a map file for your game (perhaps with a map format version number). Then you'd have sections describing each of the main elements in the Map structure. You'd allocate the Map (malloc() et al), and then load the data from the file into the structure.

于 2013-05-27T17:50:37.610 回答