summaryrefslogtreecommitdiff
path: root/cppuhelper
diff options
context:
space:
mode:
Diffstat (limited to 'cppuhelper')
-rw-r--r--cppuhelper/source/loadsharedlibcomponentfactory.hxx2
-rw-r--r--cppuhelper/source/servicemanager.cxx45
-rw-r--r--cppuhelper/source/servicemanager.hxx4
-rw-r--r--cppuhelper/source/shlib.cxx77
4 files changed, 94 insertions, 34 deletions
diff --git a/cppuhelper/source/loadsharedlibcomponentfactory.hxx b/cppuhelper/source/loadsharedlibcomponentfactory.hxx
index 7062d86fc494..df6e2269e381 100644
--- a/cppuhelper/source/loadsharedlibcomponentfactory.hxx
+++ b/cppuhelper/source/loadsharedlibcomponentfactory.hxx
@@ -35,7 +35,7 @@ void 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);
} }
diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx
index 780fe02ad70b..6d2321c3b9b1 100644
--- a/cppuhelper/source/servicemanager.cxx
+++ b/cppuhelper/source/servicemanager.cxx
@@ -686,9 +686,9 @@ cppuhelper::ServiceManager::Data::Implementation::createInstance(
bool singletonRequest)
{
css::uno::Reference<css::uno::XInterface> inst;
- if (constructor != nullptr) {
+ if (constructor) {
inst.set(
- (*constructor)(context.get(), css::uno::Sequence<css::uno::Any>()),
+ constructor(context.get(), css::uno::Sequence<css::uno::Any>()),
SAL_NO_ACQUIRE);
} else if (factory1.is()) {
inst = factory1->createInstanceWithContext(context);
@@ -706,8 +706,8 @@ cppuhelper::ServiceManager::Data::Implementation::createInstanceWithArguments(
bool singletonRequest, css::uno::Sequence<css::uno::Any> const & arguments)
{
css::uno::Reference<css::uno::XInterface> inst;
- if (constructor != nullptr) {
- inst.set((*constructor)(context.get(), arguments), SAL_NO_ACQUIRE);
+ if (constructor) {
+ inst.set(constructor(context.get(), arguments), SAL_NO_ACQUIRE);
//HACK: The constructor will either observe arguments and return inst
// that does not implement XInitialization (or null), or ignore
// arguments and return inst that implements XInitialization; this
@@ -797,7 +797,7 @@ void cppuhelper::ServiceManager::loadImplementation(
"Cannot expand URI" + implementation->info->uri + ": " + e.Message,
static_cast< cppu::OWeakObject * >(this));
}
- cppuhelper::ImplementationConstructorFn * ctor = nullptr;
+ cppuhelper::WrapperConstructorFn ctor;
css::uno::Reference< css::uno::XInterface > f0;
// Special handling of SharedLibrary loader, with support for environment,
// constructor, and prefix arguments:
@@ -808,27 +808,8 @@ void cppuhelper::ServiceManager::loadImplementation(
uri, implementation->info->environment,
implementation->info->prefix, implementation->info->name,
implementation->info->constructor, this, &ctor, &f0);
- if (ctor != nullptr) {
+ if (ctor) {
assert(!implementation->info->environment.isEmpty());
- css::uno::Environment curEnv(css::uno::Environment::getCurrent());
- if (!curEnv.is()) {
- throw css::uno::DeploymentException(
- "cannot get current environment",
- css::uno::Reference<css::uno::XInterface>());
- }
- css::uno::Environment env(
- cppuhelper::detail::getEnvironment(
- implementation->info->environment,
- implementation->info->name));
- if (!env.is()) {
- throw css::uno::DeploymentException(
- ("cannot get environment "
- + implementation->info->environment),
- css::uno::Reference<css::uno::XInterface>());
- }
- if (curEnv.get() != env.get()) {
- std::abort();//TODO
- }
}
} else {
SAL_WARN_IF(
@@ -864,7 +845,7 @@ void cppuhelper::ServiceManager::loadImplementation(
}
css::uno::Reference<css::lang::XSingleComponentFactory> f1;
css::uno::Reference<css::lang::XSingleServiceFactory> f2;
- if (ctor == nullptr) {
+ if (!ctor) {
f1.set(f0, css::uno::UNO_QUERY);
if (!f1.is()) {
f2.set(f0, css::uno::UNO_QUERY);
@@ -1978,7 +1959,15 @@ void cppuhelper::ServiceManager::preloadImplementations() {
else
{
// get function symbol component factory
- fpFactory = aModule.getFunctionSymbol(iterator->second->info->constructor);
+ aTargetEnv = cppuhelper::detail::getEnvironment(iterator->second->info->environment, iterator->second->info->name);
+ if (aSourceEnv.get() == aTargetEnv.get())
+ {
+ fpFactory = aModule.getFunctionSymbol(iterator->second->info->constructor);
+ }
+ else
+ {
+ fpFactory = nullptr;
+ }
}
css::uno::Reference<css::lang::XSingleComponentFactory> xSCFactory;
@@ -2002,7 +1991,7 @@ void cppuhelper::ServiceManager::preloadImplementations() {
}
if (!iterator->second->info->constructor.isEmpty() && fpFactory)
- iterator->second->constructor = reinterpret_cast<ImplementationConstructorFn *>(fpFactory);
+ iterator->second->constructor = WrapperConstructorFn(reinterpret_cast<ImplementationConstructorFn *>(fpFactory));
iterator->second->factory1 = xSCFactory;
iterator->second->factory2 = xSSFactory;
diff --git a/cppuhelper/source/servicemanager.hxx b/cppuhelper/source/servicemanager.hxx
index ca0021370545..5f6efd094dd5 100644
--- a/cppuhelper/source/servicemanager.hxx
+++ b/cppuhelper/source/servicemanager.hxx
@@ -50,6 +50,8 @@ typedef css::uno::XInterface * SAL_CALL ImplementationConstructorFn(
}
+typedef std::function<css::uno::XInterface * (css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const&)> WrapperConstructorFn;
+
typedef cppu::WeakComponentImplHelper<
css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
css::lang::XMultiComponentFactory, css::container::XSet,
@@ -149,7 +151,7 @@ public:
enum Status { STATUS_NEW, STATUS_WRAPPER, STATUS_LOADED };
std::shared_ptr< ImplementationInfo > info;
- ImplementationConstructorFn * constructor;
+ WrapperConstructorFn constructor;
css::uno::Reference< css::lang::XSingleComponentFactory > factory1;
css::uno::Reference< css::lang::XSingleServiceFactory > factory2;
css::uno::Reference< css::lang::XComponent > component;
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