简体   繁体   中英

tricky C problem. dynamic function call

I am writing a program in C/C++( but c++ class should not be involved ) which is divided into 2 parts. The first is basic need for threads and processes. The second is for users to customizing their own functions. the module is like, what puzzles me is the user-customizing functions.

My Need is as following: Users can create a new *.c file in a given folder, they can write their own functions.

after they made their own functions, and compilation, i provide them with an interface maybe via socket or http, or argv command. they can evoke the functions they defined before. they only give me a string like "own_funciton", and then I call the function they defined.

The question is : how to do this? 

How can i connect the strings and the functions???

I think maybe MACRO may be a solution, I ask users to define their function like this: This is just an example

BEGIN_FUNCTION (own_funcion)
{
   //function body
}
END_FUNCTION

HEED :when users add their new functions, whole system need to be recompiled.

you can do something in the MACRO BEGIN_FUNCTION to store the function string and the function pointer.. But I dont know how to write the MACRO specifically.. Do you have any advice

Mh, this sounds a bit like a plugin architecture to me - in this case this question might help you: What's safe for a C++ plug-in system? I guess you would need to write some generic plugin and your macro provides the glue to fit in the user defined functions and hiding the complex stuff.

You could also have a look at cppunit ( http://sourceforge.net/apps/mediawiki/cppunit/index.php?title=Main_Page ) which essentially enables you to write some functions, wrap them in macros which provide the glue to the cppunit framework and then let them run in a generic testrunner. But it doesn't sound like an easy task. Using some scripting language like lua seems way easier.

Update : There are some c interpreters out there, for example Cint ( http://root.cern.ch/drupal/content/cint ). And appartenly TCC ( http://bellard.org/tcc/ ) supports interpreter style calling (I guess it's inline compiling and execution). I have not used these tools that way but they might ease the pain around the "having to compile it into a dynamic dll" problem. Although I still would like to hear the rational to go down such a path instead of using a scripting language like Lua which is way more suitable for those purposes.

This sounds like a homework related question on how to deal with dynamic library loading, which is how most plug-in systems are built. Read how dynamic library loading is implemented in your platform.

As an example, in linux, you would look at dlopen / dlclose / dlsym functions. Basically the user implements a .so object, and when your application loads it opens the .so file with dlopen , once the library has been loaded, and the user enters a string, you can look for the specific function name with dlsym and call it through the function pointer. Once you have finished with the library, you release it with dlclose .

There are libraries that can help a bit in here, like Boost.Extension, that provide a multi platform interface to the underlying OS calls.

You have many options

1) If your functions are small, you can make a macro that simply declares a function and adds function to an map of pointers to functions of your type (typedef your function)

int FunctionName()
{
   //user code
}
map["FunctionName"] = FunctionName;

a macro that does that is not hard to write

when you want to execute, simply select function function from map and call it

2) you your functions are larger you must consider a plugin system. Dlls that export a function. On "server" you can enum and load those dlls and exect requested function

3) A nice version where be using a script engine that allows users to execute scrips on the server. You can achieve this my using IActiveScript or one of the many free script engines available.

Edit :

4) One more possibility that came in my mind.

  • Add your .c files to a dll project.
  • Add __declspec( dllexport ) modifier to every function you wnat to add (eventually trough the macro)
  • Enum exported function like this
 void EnumDllFunctions() { BYTE *hMod = (BYTE*)GetModuleHandle("KERNEL32.DLL"); IMAGE_NT_HEADERS *pnt = (IMAGE_NT_HEADERS*)&hMod[PIMAGE_DOS_HEADER(hMod)->e_lfanew]; IMAGE_EXPORT_DIRECTORY *exp = (IMAGE_EXPORT_DIRECTORY*)&hMod[pnt->OptionalHeader.DataDirectory->VirtualAddress]; DWORD *dwFunctions = (DWORD*)&hMod[exp->AddressOfNames]; for (DWORD ctr = 0; ctr < exp->NumberOfNames; ctr++) { printf("%s\\n", (char*)&hMod[dwFunctions[ctr]]); } 

听起来您正在寻找外部功能接口,例如libffi

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM