Personally, the way I would do this is to have a virtual class, call it MPluginImplementation for the sake of explaining here. Then you can have subclasses like MRecastPluginImplementation which, in StartPlugin, get initialised and added into the plugin system.
Obviously, if you're going to be calling C(++) functions from other code, you'll be linking to the headers of the plugin library anyway, so you can add a wrapper macro into it. This is entirely pseudocode and not even compiled, let alone tested, but something like:
#define MPLUGIN_IMPLEMENTATION_DECLARE(name) \
name* MGet##name() { return (name*)MPlugin::staticGetPluginImplementation(#name); } \
bool M##name##Exists() { return MGet##name() != 0; }
Then you can do things like
if(MRecastExists())
MGetRecast()->findPath(start, end, &path);
Of course, you would have to add some mapping of names to MPluginImplementation classes, I suggested just having them static within MPlugin, but they can really be kept anywhere.
It really depends, I know a lot of code designers don't like the whole "everything is an object" thing and shoehorning things into OO design when they don't need to be, but I think when it comes to plugins, it's quite nice to have one central plugin object that you can interface with. It also makes any mapping much simpler because you only have to do one lookup for all functions, rather than one lookup per function.