summaryrefslogtreecommitdiff
path: root/cppuhelper/source/shlib.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'cppuhelper/source/shlib.cxx')
-rw-r--r--cppuhelper/source/shlib.cxx77
1 files changed, 73 insertions, 4 deletions
diff --git a/cppuhelper/source/shlib.cxx b/cppuhelper/source/shlib.cxx
index 0cffab6783f8..fa88cc4b484c 100644
--- a/cppuhelper/source/shlib.cxx
+++ b/cppuhelper/source/shlib.cxx
@@ -160,6 +160,70 @@ css::uno::Reference<css::uno::XInterface> invokeComponentFactory(
}
}
+extern "C" void getInstance(va_list * args) {
+ cppuhelper::ImplementationConstructorFn * fn = va_arg(*args, cppuhelper::ImplementationConstructorFn *);
+ void * ctxt = va_arg(*args, void *);
+ assert(ctxt);
+ void * argseq = va_arg(*args, void *);
+ assert(argseq);
+ void ** instance = va_arg(*args, void **);
+ assert(instance);
+ assert(*instance == nullptr);
+ *instance = (*fn)(static_cast<css::uno::XComponentContext*>(ctxt),
+ *static_cast<css::uno::Sequence<css::uno::Any> const*>(argseq));
+}
+
+cppuhelper::WrapperConstructorFn mapConstructorFn(
+ css::uno::Environment const & source, css::uno::Environment const & target,
+ cppuhelper::ImplementationConstructorFn *const constructorFunction)
+{
+ if (!(source.is() && target.is())) {
+ throw css::loader::CannotActivateFactoryException(
+ "cannot get environments",
+ css::uno::Reference<css::uno::XInterface>());
+ }
+ if (source.get() == target.get()) {
+ return cppuhelper::WrapperConstructorFn(constructorFunction);
+ } else {
+ // note: it should be valid to capture these mappings because they are
+ // ref-counted, and the returned closure will always be invoked in the
+ // "source" environment
+ css::uno::Mapping mapTo(source, target);
+ css::uno::Mapping mapFrom(target, source);
+ if (!(mapTo.is() && mapFrom.is())) {
+ throw css::loader::CannotActivateFactoryException(
+ "cannot get mappings",
+ css::uno::Reference<css::uno::XInterface>());
+ }
+ return [mapFrom, mapTo, target, constructorFunction]
+ (css::uno::XComponentContext *const context, css::uno::Sequence<css::uno::Any> const& args)
+ {
+ void *const ctxt = mapTo.mapInterface(
+ context,
+ cppu::UnoType<css::uno::XComponentContext>::get());
+ if (args.getLength() > 0) {
+ std::abort(); // TODO map args
+ }
+ void * instance = nullptr;
+ target.invoke(getInstance, constructorFunction, ctxt, &args, &instance);
+ if (ctxt != nullptr) {
+ (*target.get()->pExtEnv->releaseInterface)(
+ target.get()->pExtEnv, ctxt);
+ }
+ css::uno::XInterface * res = nullptr;
+ if (instance == nullptr) {
+ return res;
+ }
+ mapFrom.mapInterface(
+ reinterpret_cast<void **>(&res), instance,
+ cppu::UnoType<css::uno::XInterface>::get());
+ (*target.get()->pExtEnv->releaseInterface)(
+ target.get()->pExtEnv, instance);
+ return res;
+ };
+ }
+}
+
}
void cppuhelper::detail::loadSharedLibComponentFactory(
@@ -167,13 +231,13 @@ void cppuhelper::detail::loadSharedLibComponentFactory(
rtl::OUString const & prefix, rtl::OUString const & implementation,
rtl::OUString const & constructor,
css::uno::Reference<css::lang::XMultiServiceFactory> const & serviceManager,
- ImplementationConstructorFn ** constructorFunction,
+ WrapperConstructorFn * constructorFunction,
css::uno::Reference<css::uno::XInterface> * factory)
{
assert(constructor.isEmpty() || !environment.isEmpty());
assert(
(constructorFunction == nullptr && constructor.isEmpty())
- || *constructorFunction == nullptr);
+ || !*constructorFunction);
assert(factory != nullptr && !factory->is());
#if defined DISABLE_DYNLOADING
assert(!environment.isEmpty());
@@ -273,8 +337,13 @@ void cppuhelper::detail::loadSharedLibComponentFactory(
+ "\" in component library <" + uri + ">"),
css::uno::Reference<css::uno::XInterface>());
}
- *constructorFunction = reinterpret_cast<ImplementationConstructorFn *>(
- fp);
+ css::uno::Environment curEnv(css::uno::Environment::getCurrent());
+ *constructorFunction = mapConstructorFn(
+ curEnv,
+ (environment.isEmpty()
+ ? getEnvironmentFromModule(mod, curEnv, implementation, prefix)
+ : getEnvironment(environment, implementation)),
+ reinterpret_cast<ImplementationConstructorFn *>(fp));
}
mod.release();
#endif