I am trying to implement an expert system in C. I have written each rule in the expert system as a function. However, I want my system to be more flexible and can process these rules from an external file specified at run time rather than hard-coded. This will provide more efficiency as the user can modify these rules any time Something like a configuration file but not sure how to do it.

A friend of mine told me to use function pointers and then use a shared object or DLL to specify the external functions. Then the config file could tell the code where the DLL is and what the corresponding function names are.

I have come up with this code to read from shared library
pro.c

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

typedef int (*simple_demo_function)(int);


int main(void) {
 const char *error;
 void *module;
 simple_demo_function demo_function;

 /* Load dynamically loaded library */
 module = dlopen("rules.so", RTLD_LAZY);
 if (!module) {
   fprintf(stderr, "Couldn't open rules.so: %s\n",
           dlerror());
   exit(1);
 }

 /* Get symbol */
 dlerror();
 demo_function = dlsym(module, "hello");
 if ((error = dlerror())) {
   fprintf(stderr, "Couldn't find hello: %s\n", error);
   exit(1);
 }

 /* Now call the function in the DL library */
 (*demo_function)(10);

 /* All done, close things cleanly */
 dlclose(module);
 return 0;
}

And this is rules.c

#include <stdio.h>

int hello(int a)
{
return a*10;
}

This is my script

#!/bin/sh
# Shared library demo

# Create shared library's object file, rules.o.

gcc -fPIC -Wall -g -c -o rules.o rules.c

# Create shared library.
.

gcc -g -shared -Wl,-soname,rules.so.0 \
    -o rules.so.0.0 rules.o -lc

# At this point we could just copy rules.so.0.0 into
# some directory, say /usr/local/lib.

# Now we need to call ldconfig to fix up the symbolic links.
 
/sbin/ldconfig -n .

# Set up the linker name.

ln -sf rules.so.0 rules.so

# Compile pro program file.

gcc -Wall -g -c pro.c

# Create program pro.

gcc pro.c -o pro -L. -lrules

# Execute the program.  Note that we need to tell the program
# where the shared library is, using LD_LIBRARY_PATH.

LD_LIBRARY_PATH=. 
./pro

But I can force it to work

A friend of mine told me to use function pointers and then use a shared object or DLL to specify the external functions. Then the config file could tell the code where the DLL is and what the corresponding function names are.

That's one way to do it, but it isn't as flexible as it could be. It requires anyone creating rules for your expert system to write them in C and compile them before they can be used, which limits your rule-writing audience. As a suggestion, it would be easier to use if rules were specified as code in a text file that people wouldn't have to compile on their own. This means more work for you, but if you go with a well-known scripting language like Lua, it wouldn't be too difficult.

> But I can force it to work

Please elaborate.

Sorry I forgot to type the error.
When I run the compilation script, it returns with is error
Couldn't open rules.so: rules.so: cannot open shared object file: No such file or directory

This seems to complicate it more as I have to use this external engine to run my code. little bit lost of how to implement this fixable system in C in a simple and efficient way !

That's one way to do it, but it isn't as flexible as it could be. It requires anyone creating rules for your expert system to write them in C and compile them before they can be used, which limits your rule-writing audience. As a suggestion, it would be easier to use if rules were specified as code in a text file that people wouldn't have to compile on their own. This means more work for you, but if you go with a well-known scripting language like Lua, it wouldn't be too difficult.

First of all, try an explicit path: module = dlopen("./rules.so", RTLD_LAZY); Second, the environment variables are not exported by default. LD_LIBRARY_PATH=. is not enough, you need export LD_LIBRARY_PATH Finally, (it doesn't cause the problem though), you don't have to link your so: -lrules is unnecessary.
Maybe, there's more (I don't have a linux box at a moment).

This seems to complicate it more as I have to use this external engine to run my code.

You're right. Adding a scripting engine does complicate things for you, the developer, but it makes things less complicated for rule writers. This may not be important for your project; I'm just offering an alternative.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.