Date: prev next · Thread: first prev next last
2014 Archives by date, by thread · List index


On 06/18/2014 10:58 PM, Lionel Elie Mamane wrote:
On Wed, Jun 18, 2014 at 05:04:02PM +0200, Stephan Bergmann wrote:
Short answer (from just browsing the top of FOO.patch):  Use
css::uno::Reference<X> only for (C++ classes representing) UNO interfaces,
and use rtl::Reference<C> for C++ classes implementing UNO objects.

Aha. This works. If you feel like explaining the C++-technical reason
behind why we need different Reference implementations for the two
cases... Feel free.

As C++ UNO for largely historic reasons does not use virtual inheritance, a css::uno::Reference for a multiple-inheritance interface type like css.uri.XVndSunStarExpandUrlReference (deriving from both css.uri.XUriReference and css.uri.XVndSunStarExpandUrl, each in turn deriving from css.uno.XInterface) faces a problem. The Reference ctor has a pointer pInterface to css::uri::XVndSunStarExpandUrlReference and needs to call css::uno::XInterface::acquire through it. But css::uno::XInterface is an ambiguous base class of css::uri::XVndSunStarExpandUrlReference, so calling pInterface->acquire() will not compile.

The trick is that we know that all compilers lay out the vtables in roughly the same way: No matter how many types a given type X derives from, a pointer to X points to a vtable containing function pointers for X's first base (if any) followed by function pointers for X's own members (if any). So as long as X represents any UNO interface type, the css::uno::Reference<X> ctor can do that dirty trick of reinterpret-casting pInterface to css::uno::XInterface* and calling acquire through that reinterpret-casted pointer and be sure it hits a vtable slot that calls the object's implementation of acquire (without needing adjustment of the this pointer). All to allow for a single generic implementation of the css::uno::Reference<X> ctor that compiles fine regardless of X.

Now, if you break the assumption that X represents a UNO interface type, that reinterpret_cast trick potentially breaks down. connectivity::odbc::OResult derives from comphelper::OBaseMutex, connectivity::IResultSetHelper, OResultSet_BASE (aka cppu::WeakComponentImplHelper12 through which it derives from the various UNO interface types it implements), etc., in that order, so the vtable layout differs from that of a UNO interface type, and starts with vtables for comphelper::OBaseMutex and connectivity::IResultSetHelper. And the slot the reinterpret_cast hack mis-computes happens to be the slot for connectivity::IResultSetHelper::getDriverPos.

An alternative solution for the dilemma of a generic css::uno:Reference implementation could be to let cppumaker emit additional type-trait information how to cast between XInterface and any emitted interface type, and use that in the generic css::uno::Reference implementation. That could probably make a "bad" css::uno::Reference of an implementation class either silently do the right thing or cause a compilation error.

I assume I can mix-and-match both, they will use the same (shared)
counters for reference counting?

Yes, both css::uno::Reference<T> and rtl::Reference<T> rely on T's acquire and release functions.

I see there is no rtl::WeakReference, and no automatic conversion from
rtl::Reference to css::uno::(Weak)Reference; oh well, I can add
".get()" here and there.

Yes, use .get() for that. (Theoretically, there could be implicit conversion between css::uno::Reference and rtl::Reference, but nobody ever bothered to add it. Or there was a catch I momentarily can't remember.)

Stephan

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.