[sldev] Plugin system - first code drop

Soft Noel soft at softnoel.org
Tue Feb 27 00:28:08 PST 2007

On Mon, February 26, 2007 11:26 pm, Tim Shephard wrote:
> I agree.  This is important as that contract  should be ideally
> near-perfect and very resistant to change as it would be the function
> pointer table loaded from the DLL that the plugin developer exposes
> and relies on.

Sure, this is the reasoning for the LLJack versioning system and for
breaking up the bridge API into multiple interface types. This lets us
invalidate only select portions of the API. I don't want to rule out
interfaces handing over a raw mesh and letting someone go all medieval on
it for a SIGGraph paper. But I want to be sure that kind of flexibility
doesn't screw things up for the plugin that only requests a UI interface
and a simple object positioning and texturing interface. The deep graphics
API can last just one client version, while the others can be maintained
over a dozen releases.

>> One tempting approach is to more or less replicate the LLFloater
>> interface
>> inside the plugin SDK, with the floater proxy as a bridge between the
>> real
>> and plugin implementations, boiling things down to the simplest
>> representation of events and data changes that can be expressed through
>> LLJack versioned interfaces.
> I think you're saying here that plugin developers would create a
> plugin-side class and would export that class or at least its
> individual functions to the core code base.

I'm figuring we do the LLFloater reimplementation work ourselves, not the
plugin developer. I see as much work to be done on the plugin SDK library
side as on the viewer side. The things that make an interface clean and
safe don't always make them pretty.

> That seems like an ideal approach if you can expose the functions in
> the plugin to the core code base in a safe way.
> However, my understanding is the best way to expose across dlls is
> with C extern stubs rather than classes, even if no inheritance goes
> on.
> C++ has a lot of mysterious things happening which I'm not sure
> translate very well on a cross platform basis.  Not being a cross
> platform expert, I certainly can not comment confidently.

You have three main concerns when exposing C++ classes in a shared
library. The first is that virtual function table implementations are not
specified by the language specification, and are compiler-dependent. The
second is that you can't extern "C" a class method to avoid name mangling
which can yield strange symbols and give binding problems. The third is
that objects with inline or statically called methods attach an
implementation contract. For example if we pass an LLString class, the
plugin has to carry exactly the same LLString implementation or it can
stomp on data when its copy of the statically bound functions think the
string pointer was the second item in the class, rather than the third.

In practice, Visual Studio is the law of the land under Windows and MS
won't change the C++ ABI for legacy reasons. If we decide we want to
support Borland Builder or other compilers, I can research whether they've
made their ABI match MS'. Linux (g++) migrated to the common Itanium ABI
in 2001, and Apple have committed to backward ABI compatibility as well.
That takes care of the first two points.

Unfortunately, the third pitfall is with us even if we use named C-style
binding, so long as we pass even a single class as a parameter. :/ It's
something we just have to avoid doing unless passing std library classes
(ie std::string), as if those ever change in an incompatible way, we're
going to be rebuilding the client and plugin SDK anyway.

We *do* get two big things by expressing the interface via C++ classes.
The first is that the names carry mangling. This lets us know immediately
if we screw up and make a change to the number of parameters a function
takes, try building with signed ints on one side and unsigned on the
other, or add a return value to a method. The second is that it also gives
us link errors instead of run-time errors if we mess up a function name
between the two sides.

> However, that being said, it would be nice if someone had the cross
> platform expertise to proof of concept that if they had the sufficient
> motivation to do so.   It might be an opportunity to make  history in
> the world of plugin architectures... :)
> I included a win32 proof of concept for exposing classes across DLLs
> in a recent attachment on a previous email, so they could start with
> that.

The LLJacks in the LLJackBundle are already C++ classes exposed across.
It's working via dylibs right now, but as soon as AMD gets me going with
the Windows VPN, I'll show it working there as well. Or I'll suffer
humiliating defeat after being so cock-sure about it!

More information about the SLDev mailing list