Jump to content
  • Advertisement
Sign in to follow this  
paulecoyote

[C++] Plugins, confused about implementation (in Ogre for example)

This topic is 4769 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm getting my head around Ogre and learning a few things on the way - one of the things I'm quite interested in is how Ogre has done plugins. I found a sound plugin http://www.ogre3d.org/phpBB2/viewtopic.php?t=7234 with a view to posting back an improved version but have noticed something about the linkage. None of the ogre supplied plugns seem to be referenced as a .lib file in any of the example projects, yet in Ogre.h (which is part of ogremain but not used by ogremain itself) many of the plugins h files are included. That ogre.h is referenced in ExampleApplication, yet none of the example applications reference any of the lib files, and neither does ogremain. Now the sound plugin and demo DOES link to the plugin .lib file and is part of the plugin config file too, so I'm guessing the original author did not develop the plugin in the same way the other plugins have been. What I don't understand (and please do excuse my ignorance) is how the other plugins are refering to the plugins' include files and compiling without external linkage errors. It seems to me that something clever is going on, because it is not being linked up directly to the lib files and the examples aren't including the source files, only the header files - yet the examples can still use classes exported from the dll. So at compile time if I were to use Particle effects yet not have the particle effects plugin configured to be used or even there, and that will compile fine using exported classes and all with no linkage errors yet, predictably not working when it comes to runtime. I would like to bring the sound plugin up to speed with the rest of the ogre framework as it stands, but this bit has got me puzzled. I'm sure it's obvious to one of you guys and you'll have an explanation / link you'll share with me [smile] I know this is a bit Ogre specific and have posted to the Ogre forums but I am unaware about how active they really are - plus this is probably a generic programming techinique anyway so I think you guys at gamedev probably have some handy links kicking around. [grin]

Share this post


Link to post
Share on other sites
Advertisement
Without looking at what Ogre actually does, I see two probable posibilities:

0) You are mistaken and it does in fact include libraries.

1) It is actually linking the library, just in a different way using "#pragma comment(lib, "somekindoflibrary")" in a source file somewhere.

2) It is using LoadLibrary to load the library, and the headers you are including are not definitions for external functions (that the linker must find in a library), but contain the definitions to use functions accessed with GetProcAddress.

Share this post


Link to post
Share on other sites
I don't know how Ogre does things specifically but, in case that's the kind of things you want to know, here's my understanding of plugin architectures

A plugin architecture is generally based on manual dynamic loading of the library the plugin is bundled in. While it is most common for a DLL to be automatically loaded by an executable because its import (LIB) file has been linked at compile time, it is also possible to do so programmatically. For example, in Win32, by using the LoadLibrary() function. Once the library is loaded, it is possible to get pointers to the individual functions, by name, for example using the GetProcAddress() function (in Linux you would use dlopen() and dlsym()). This process is made somewhat more complex in C++ by the name mangling process, which embeds type information into a function's name (you probably have noticed that already in linker errors).

This is where the main application's play a role. By referencing appropriate headers and linking to relevant libraries them, the plugin conforms to a well-specified interface, and is constrained to provide those functions - with the appropriate types - that the application knows to look for in a plugin. This way, the plugin can be used even though it was not linked to when the main application was compiled.

A bit like how the C runtime you (implicitely) link to knows it has to execute the main() function of the program after all the initializations have been done.

Share this post


Link to post
Share on other sites
Thanks guys. I think it's actually doing a bit of both looking in to it. There are some abstract classes defined in ogremain that are built upon in the plugins (so the plugin includes ogremain.lib).

Though I am still confused about how it manages to use the include files and class exports - I think that even though the exports are defined they are not actually used in the examples because the plugins base things on a set of classes defined in the main ogre dll.

The ogre.h file is confusing because it includes things from multiple directories across the framework, including the plugin directories. But as the main ogre project doesn't actually use that file, it only contains it... it doesn't matter.

I think this is one I just needed to talk out to get my head around it, thanks for the bouncing of ideas [smile]

Although I'm still not absoutely sure what is going on, I think it means that anything completely foreign to the framework, (like sound or network) can be made in to a plugin following the rules and treated like an entity - but it has to be statically linked. Thing is when you do that you have to register it with the plugin manager and that will dynamically load the thing in too.

Would be nice to actually talk with someone who knows what the code is all about, still it's alot easier to fathom then some code I've come across.

Share this post


Link to post
Share on other sites
Okay, so after going through ogre for a while here's my impressionof how it works.

1. DynamicLibrary manager is created by the kernel. This objects loads DLLs using LoadLibrary, and retrieves functions using GetProcAddress. They aren't called directly, but thats the end result. So a DLL is requested by name and it is loaded into memory.

2. Once the library is loaded the client asks for a specific function, usually a factory function. This returns a pointer to a fuction who's sole job is to create one of the plugins objects.

3. The client has included the plugins .h files so it is aware of the objects' interfaces. So it calls the function its been given by the dynamic library manager, which returns a pointer to the object requested in terms of its interface class.

4. Now the client has a pointer to an object from the plugin and they use it as if it were native to the core engine.

5. The only difference is when the object is destroyed that it cannot just be deleted, as it was created on the plugin dll's heap. So the client requests another function from the dynamic library manager, this time a deletion function, whose sole prupose is to delete the plugin object.

6. When Ogre is shutting down the dynamic lib manager itterates through all the open libraries and releases them.

I'm fairly sure thats whats going on.

Share this post


Link to post
Share on other sites
I'm working with OGRE in a current project and am using a few of the available plugins. From what I understand of OGRE's plugin system is each plugin dll is required to implement a dllStartPlugin() and dllStopPlugin which is called by the DynLibManager within OGRE.

What each of these functions essentially does is to register themselves within OGRE - for a scene manager plugin when the dll is loaded the custom scene manager will register with the Root object under a pre-determined type, ST_GENERIC etc so when you ask the root object for a ST_GENERIC scene manager you actually get the pointer which was registered through the plug-in dll.

Since the objects/factories registered through the plug-ins are often dynamically allocated inside the plug-in dll then in the call to dllStopPlugin it can release all allocated resources when OGRE itself is shutdown or you request a manual unload of the plug-in.

Many of the plug-ins are extending existing behaviour inside OGRE so specific knowledge of the plug-in isn't required, they can be dynamically loaded through methods like LoadLibrary() without the end user having to worry about linking in multiple libs apart from the main OGRE ones.

Share this post


Link to post
Share on other sites
I think I could only rewrite the sound thing I found as a true plugin if there was some kind of abstract "MovableObject" factory I could register the plugin with. As far as I can tell there isn't anything generic enough currently exposed to allow something as generic as that to be attached to a scenenode imported from a library. I mean I could fudge it so a sound is an extension of a particle or something, but that smells bad to me.

I suppose a sound plugin could be programmed as a scene manager, but I'm wondering if making a plugin rather then just having a seperate statically linked module that provides sound and can use Ogre objects is really worth the effort.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!