You can only call public functions, so that rules out many things.
The way MetaEng works is by keeping a table of function names to pointers, so anything that is registered to MetaEng is available to anything else. The way this is cool is that if the lookup and addition functions are propogated, then plugins can contribute back into the main pool.
However, it gets iffy. If say an AMX plugin wants to call a random function in a Perl script, it's not possible without an interface that connects the two. To help this interface, there is a very very simple class in MetaEng called CForward that basically pushes references into the scripting engines... the only problem is that not every language has a definitive way of pushing parameters.
For going from *->AMX is not difficult at all, writing forwards for AMX is trivial. But to C/C++ it's not since parameters can't nicely pushed randomly.
Example, say you have this (example):
Code:
$f = call_function($engId, $plugId);
call_push_int($f, $param1);
call_push_int($f, $param2);
call_push_float($f, $param3);
call_push_end($f);
The perl engine would build a generic block of data describing the forward, The MetaEng would get this block and pass it on where it's going. But the engine in question must have a way to decode that block generically. This is not possible in C. The block of data looks like this:
void *blkParams[PARAMS*2+1]
blkParams[0] = numParams
blkParams[i+1] = pointer to parameter
blkParams[i+2] = has the param type
So the AMX engine can easily say "oh, just build a new block of data based on this, then call amx_Exec()". In C, a specific function has to be rewritten since you can't variably push C arguments without assembly.
So I guess what I'm saying is this will be TRIVIAL to implement, but in practice unless you know what you're doing you will be able to easily crash C plugins, if you call a function in a C plugin and don't know what you're doing. Public functions in C will have to be wrapped, like this:
Code:
METAENG_API int call_forward(void *blk)
{
actual_call(*(int *)(blk[1]));
}
actual_call(int a)
{
//....
}
It's messy, yeah. I plan on making some nice macros for the block stuff but I don't see another way to do this ;\
Well, I could do it in assembly which would actually be way easier at this rate. Lemme think about it