Can someone please explain what the following paragraph means in simpler and elaborate terms?
Class_loader is a ROS-independent package that allows one to dynamically load exported C++ classes during runtime from a runtime library (i.e. .so/.dll file) and create objects of those classes. What makes a class loaded through class_loader different from just linking against a runtime library and using classes from it is that your code does not require the definition of the class (i.e. the header file for the class) in your client code. Classes loaded in this fashion are also often called plugins.
I don't know how much you know about shared libraries, ros ecosystem C++ inheritance but here are some basic things to know
ROS comes with two packages
class_loader: loads shared libraries during runtime
pluginlib: ros specific class loader based on class_loader. This helps you to find and load the libraries within ros ecosystem.
Here is a basic setup
You have a library called MyLibrary compiled as "libMyLibrary.so"
In this library you have an abstract interface class MyBase and several implementations of it:
// file: MyBase.h
class MyBase{
public:
virtual void foo() = 0;
};
-------
// file: MyBaseMainImplementation.h
class MyBaseMainImplementation: public MyBase{
public:
void foo();
};
// file: MyBaseMainImplementation.cpp
void MyBaseMainImplementation::foo() { std::cout << "bar" << std::endl; };
// Make this class loadable from other libraries. This enables it to act like a
// plugin
CLASS_LOADER_REGISTER_CLASS(MyBaseMainImplementation, MyBase);
-------
// file: MyBaseOtherImplementation.h
class MyBaseOtherImplementation: public MyBase{
public:
void foo();
};
// file: MyBaseOtherImplementation.cpp
void MyBaseMainImplementation::foo() { std::cout << "foo bar" << std::endl; };
// Make this class loadable from other libraries. This enables it to act like a
// plugin
CLASS_LOADER_REGISTER_CLASS(MyBaseOtherImplementation, MyBase);
In a second library or executable (program) you want to use some implementation of MyBase but you don't know which is available during compile time. What you can do is use the class_loader to load any library during runtime which has the implementation of MyBase you want
// load libMyLibrary.so
class_loader::ClassLoader loader("libMyLibrary.so");
// create instance of a class from libMyLibrary.so
boost::shared_ptr<MyBase> my_base_impl =
loader.createInstance<MyBase>("MyBaseMainImplementation");
The only thing needed here is the header of MyBase class, i.e. MyBase.h
Back to the main question What are plugins in C++?
Well here the various implementation of MyBase, i.e. MyBaseMainImplementation and MyBaseOtherImplementation are plugins which can be loaded during runtime without linking against libMyLibrary.so. That's all there is to it.
Related
I know this was aksed and answered a a couple of times e.g.
Solution-wide #define, Is There anyway to #define Constant on a Solution Basis? and How to define a constant globally in C# (like DEBUG).
But in my case I can not use any of the suggested methods:
I'm writing on different "modules" (or plugins if you want so) for UnityProjects (kind of a package providing a certain functionality). The idea is that a developer can load a certain "module" to use in his project by importing a UnityPackage with all scripts and resources in it.
But some of these modules themselves depend on other modules. So what I tried so far was having a class Constants in each module with seperated namespaces and preprocessor definitions.
Module A
#if !MODULE_A
#define MODULE_A // BUT I WOULD NEED THIS GLOBAL NOT ONLY HERE
#endif
namespace Module_A
{
public static class Constants
{
// some constants for this namespace here
}
}
Module B
#if !MODULE_B
#define MODULE_B // BUT I WOULD NEED THIS GLOBAL NOT ONLY HERE
#endif
#if !MODULE_A // WILL BE NOT DEFINED OFCOURSE SINCE #define IS NOT GLOBAL
#error Module A missing!
#else
namespace Module_B
{
public static class Constants
{
// some constants for this namespace here
}
// and other code that might require Module A
}
#endif
But ofcourse this cannot work like this since #defines are not global but only in the current file.
Problem
For this whole idea of modules and a simple "load your modules" I can not ask the user to first make changes to the project or solution settings how e.g. suggested by this answer but instead have to use only the (c#) resources that come imported with the UnityPackage (at least with my current know-how).
Is there any way to somehow set/define those constants for the entire Unity-Project by only importing the module's UnityPackage?
Edit:
I could find a solution for 1 definition in Unity using Assets/msc.rsp. But this still wouldn't work for multiple modules since they would have to write into the same file.
After a lot of searches I've finally been able to put together a surprisingly simple solution I'ld like to share with you:
InitializeOnLoad
Unity has an attribute [InitializeOnLoad]. It tells Unity to initialize according class as soon as
Unity is launched
After any re-compiling of scripts => also after importing a new unitypackage with scripts
static Constructor
In their Running Editor Code On Launch example, they show, how to combine this with a static constructor.
From static-constructors:
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
While usually you still would have to create an instance of the class, the static constructor is "instanciated/executed" instantly when the class is initliazed, which we force using the [InitializeOnLoad] attribute.
Scripting Define Symbols
Further Unity actually has project wide defines in the PlayerSettings.
And the good part is: We also have access to them via scripting API:
PlayerSettings.GetScriptingDefineSymbolsForGroup
PlayerSettings.SetScriptingDefineSymbolsForGroup.
So what I did now is the following
Module A
This module has no dependencies but just defines a "global define" in the PlayerSettings. I placed this script somewhere e.g. in Assets/ModuleA/Editor (important is the last folder's name).
using System.Linq;
using UnityEditor;
namespace ModuleA
{
// Will be initialized on load or recompiling
[InitializeOnLoad]
public static class Startup
{
// static constructor is called as soon as class is initialized
static Startup()
{
#region Add Compiler Define
// Get the current defines
// returns a string like "DEFINE_1;DEFINE_2;DEFINE_3"
var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
// split into list just to check if my define is already there
var define = defines.Split(';').ToList();
if (!define.Contains("MODULE_A")
{
// if not there already add my define
defines += ";MODULE_A";
}
// and write back the new defines
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, defines);
#endregion
}
}
}
Module B
This module depends on Module A. So itself defines a "global define" (so later Modules can check their dependecies on Module B) but additionally it checks first, if Module A is imported. If Module A is missing, it prints an error to the Debug Console.
(You could as well throw a compiler error using #error SOME TEXT, but for some reason this is not capable of printing out the URL correctly so I decided for the Debug.LogError)
I placed this script somewhere e.g. in Assets/ModuleB/Editor
#if MODULE_A
using System.Linq;
#endif
using UnityEditor;
#if !MODULE_A
using UnityEngine;
#endif
namespace ModuleB
{
// Will be initialized on load or recompiling
[InitializeOnLoad]
public static class Startup
{
// static constructor is called as soon as class is initialized
static Startup()
{
#if !MODULE_A
Debug.LogErrorFormat("! Missing Module Dependency !" +
"\nThe module {0} depends on the module {1}." +
"\n\nDownload it from {2} \n",
"MODULE_B",
"MODULE_A",
"https://Some.page.where./to.find.it/MyModules/ModuleA.unitypackage"
);
#else
// Add Compiler Define
var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
var define = defines.Split(';').ToList();
if (!define.Contains("MODULE_B"))
{
defines += ";MODULE_B";
}
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, defines);
#endif
}
}
}
So later in other scripts of Module B I have two options (both do basically the same)
I can either check everywhere #if MODULE_A to check exactly the module this script relies on
or I can instead check #if MODULE_B to rather check with one line if all dependecies are fulfilled since otherwise I don't define MODULE_B.
On this way I can completely check all dependencies between certain modules which is awesome. The only two flaws I saw until now are:
We have to know how the define (e.g. MODULE_A) looks like for every module and if it is changed in the future it has to be changed in all depending modules as well
The "global define" isn't getting removed in case the module is deleted from the project
But well - which solution is perfect?
In general, the way I would solve this problem in C# is by defining a common set of interfaces that all your modules would contain. I think you can do this with Unity by placing the files from each module in the same location, thus allowing later installations to overwrite those same files (with, obviously, the same content). You would then put editor controls that expose properties to hold instances of those interfaces and then wire them up in the UI. You would test those properties for a value of null to determine which ones are missing.
Common.cs:
public interface IModuleA {}
public interface IModuleB {}
ModuleA.cs
public class ModuleA : IModuleA {}
ModuleB.cs
public class ModuleB : IModuleB
{
public IModuleA ModuleAInstance {get; set;}
private bool IsModuleAPresent()
{
return !ModuleAInstance == null;
}
}
The ideal way to solve it would be with a package manager and proper dependency injection, but doing that with Unity is not straightforward.
We are covering UML diagrams in one of my university modules, and we briefly covered package diagrams. I understand that in a package diagram, when there is a connection (or arrow) between two packages and it is labelled with import, it means that the contents of the target package are added to the source's public namespace, while access adds it to the private namespace and cannot be re-exported when a third package imports the original source package. My question is how would you actually implement the import and access in code? For example with Java you have;
import Java.swing.*;
As far as I know there is no access key-word, right?
Thanks
Importing a package is equivalent to importing it's all public elements. So, the visibility of import can be thought of the visibility of the elements (imported elements).
Here is an example in C# depicting the difference between "access" and "import". It is easy to map the code to Java:
namespace Logger
{
public class FileLogger
{
public void LogTimeToFile(string fileName, string time)
{
//....
}
}
}
namespace ServerTime
{
public class TimeProvider
{
public string GetTime()
{
//....
}
}
}
namespace ServerTimeLog
{
public class Logger
{
private Logger.FileLogger logger; // Logger is access but not imported
public ServerTime.TimeProvider timeProvider; // ServerTime is imported
public void LogCurrentTime()
{
logger.LogTimeToFile("c:\\log.txt", timeProvider.GetTime());
}
}
}
namespace TaskLog
{
ServerTimeLog.Logger serverTimeLogger;
public void SomeMethod()
{
// serverTimeLogger.logger ----> Inaccessible because it was accessed not imported
// serverTimeLogger.timeProvider ----> Accessible because it was imported
}
}
You wouldn't, necessarily.
Questions about relating UML constructs to source constructs in a particular language are in general meaningless. Java isn't the world's only programming language, nor is UML much good at documenting source code.
UML deals with abstracts, while source code is an implementation and therefore concrete. To bridge the gap, you need an adaptation ("profile") of UML which specifies how each source construct is represented, and there are essentially no standardized profiles for any of the common languages.
Instead, the different tool vendors choose how to represent the various source constructs for the languages where they support forward and/or reverse engineering. In tool X, the access and import stereotypes may or may not have any meaning with regard to language Y; a Java package might well be represented by a UML class.
So the question can really only be answered in the context of a specific tool and a specific language.
According to Visual Paradigm Uml help, they are very close, only " The keyword <<import>> is shown near the dashed arrow if the visibility is public; otherwise, the keyword <<access>> is shown to indicate private visibility."
I am writing (with my team) an GWT application, which parses and represent some domain specific language - for example, plays media presentation with text, video and UI controls. So the application has a set of components: ones - for holding model, ones - for control routines (controllers), and of course we have classes for View.
Now we have a problem - make it all plug-able, in the sense of:
should be one core plugin, which make all common stuff. This coer block must be an JavaScript file (one for every permutation)
should be ability to extend core classes, write custom ones - and compile it to separate JS file (one for every permutation)
Every plugin must registers (export it's classes etc) itself to the core platform, so it could be used.
Problems:
How to compile the custom stuff
separately ?
How to load plugins ?
For the second one problem i've found http://code.google.com/p/gwt-exporter/, that exports GWT classes to outer world, so they could be invoked from pure JS.
Also I have an idea to create new module for new plugin, so it will be compiled to separate file (first problem).
Have you an experience of building such architecture, have you some best practices in this case ?
I have experimented with this same question since GWT 1.5 and every time I come up with a more elegant solution they change the linker and break it. The only way that I have come up with that would work independent of linker design is to do exactly what you are talking about and create a new module for ever plug-in. Then use GWT exporter to create an abstract class that plugins must extend that would have an abstract method that would take the root element of the plugin passed to it by the core and populate it. The issue with this method is all plug-in modules must be added to the DOM on the initial load of the page because since 2.0 the iFrame linker relies on a page load event so dynamically added modules wont fully load. So because of this you will want to have the exported population method wrapped in runAsync so that you aren't downloading modules till you use them.
Edit:
Here is a rough example of what I am talking about. Please be aware that I haven't done any GWT in a couple years and there may be a better way of doing this by now.
public final class PluginManager
{
public static final PluginManager INSTANCE = new PluginManager();
private PluginManager()
{
}
private static native void loadPlugin( AbstractPlugin plugin )
/*-{
if (!$wnd.Plugins) {
$wnd.Plugins = {};
}
var name = plugin.#com.example.PluginManager.AbstractPlugin::getName()();
$wnd.Plugins[name] = $entry(plugin.#com.example.PluginManager.AbstractPlugin::load(Ljava/lang/String;));
}-*/;
private static native void unloadPlugin( AbstractPlugin plugin )
/*-{
if ($wnd.Plugins) {
var name = plugin.#com.example.PluginManager.AbstractPlugin::getName()();
delete $wnd.Plugins[name];
}
}-*/;
private static native JsArrayString getPlugins()
/*-{
if ($wnd.Plugins) {
return Object.keys($wnd.Plugins);
}
return undefined;
}-*/;
public static abstract class AbstractPlugin implements EntryPoint
{
#Override
public final void onModuleLoad()
{
PluginManager.INSTANCE.loadPlugin( this );
}
protected final void unload()
{
PluginManager.INSTANCE.unloadPlugin( this );
}
protected abstract String getName();
protected abstract void load( String rootPanelId );
}
}
I have an ATL/COM-based DLL, made using VC++ 6.0. It's used for various executables built using VB6.
I want to add some COM interfaces that will not be accessible via VB6, for the internal use of the DLL only. I want them to be COM interfaces rather than just C++ interfaces due to the fact that I'll be using them on objects which I only have COM interface references to (at the time of use).
That is, I don't know (at the time of use) that this pointer points to a CFoo; I just know that it points to an IFoo, where IFoo is a COM interface, published so that VB6 knows about it. From this IFoo pointer, I want to get an IFooInternal pointer, which every class that implements IFoo (not just CFoo) will implement. Moreover, I don't want IFooInternal to be accessible outside of the DLL itself; for example, I don't want IFooInternal to be accessible by VB6.
Any help with this would be greatly appreciated. Suggestions for alternate ways to accomplish the same overall goal would also be. Thanks in advance.
Answering my own question for the benefit of anyone who finds this thread in the future. However, please note that I am just guessing here, based on experimentation... it seems to work, at least in my specific situation, but I don't know.
First, in some appropriate header file (perhaps Hidden.h), put the following, replacing a newly generated UUID with a newly generated UUID:
#ifndef __Hidden_h__
#define __Hidden_h__
extern "C" {
#ifndef __IHidden_FWD_DEFINED__
#define __IHidden_FWD_DEFINED__
typedef interface IHidden IHidden;
#endif // __IHidden_FWD_DEFINED__
#ifndef __IHidden_INTERFACE_DEFINED__
#define __IHidden_INTERFACE_DEFINED__
EXTERN_C const IID IID_IHidden;
MIDL_INTERFACE("a newly generated UUID")
IHidden : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE get_Something (
long __RPC_FAR *pVal ) = 0;
};
#endif // __IHidden_INTERFACE_DEFINED__
}
#endif // __Hidden_h__
For how to define other types of parameters and such for a function, refer to the C++ header that was generated by MIDL from your IDL file.
Next, in the header for any class that you want to implement this interface, add the interface to the class declaration:
class ATL_NO_VTABLE CBlah :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CBlah, &CLSID_CBlah>,
public ISupportErrorInfo,
public IConnectionPointContainerImpl<CBlah>,
public IBlah,
public IHidden
Also add it to the COM_MAP:
BEGIN_COM_MAP(CBlah)
COM_INTERFACE_ENTRY(IBlah)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY(IHidden)
END_COM_MAP
And from there on out it's just a matter of adding the standard C++ declarations and definitions of the interface's functions to the class:
public:
STDMETHOD(get_Something)(long *pVal);
(...)
STDMETHODIMP CBlah::get_Something(long *pVal)
{
if ( !pVal )
{
(error handling)
}
*pVal = 37;
return S_OK;
}
I hope this helps someone in the future. I also hope that it doesn't hurt me due to it being incorrect. As I said, though, it seems to work.
This doesn't sound like a problem that necessarily needs COM. Remember: If you get an unmarshalled IFoo* from COM, it is just a normal IFoo* – not some magic COM-Thing. So what you can do is simply define a normal C++-Interface IFooInternal and then dynamic_cast your IFoo* to that.
The interfaces in Managed C++ looka bit strange to me since they allow static methods and members inside them. For example, following is a valid MC++ interface.
interface class statinterface
{
static int j;
void Method1();
void Method2();
static void Method3()
{
Console::WriteLine("Inside Method 3");
}
static statinterface()
{
j = 4;
}
};
Well, my question is that what is the use of static methods in an interface. And what happened to virtual tables etc. What will be the virtual table of the classes implementing this interface. There are lots of questions that come to mind. This type of class i.e., interface class is not equivalent to a plain abstract class since we can't have definition of non-static methods here.
I just want to know the wisdom of allowing statics in interface. This is certainly against OOP principles IMO.
The easiest way to answer this question is to use .NET Reflector to examine the assembly generated from the code.
A VTable only ever contains virtual functions, so statics simply wouldn't be included.
The language is called C++/CLI, not Managed C++ (that was something bad from way back in 2002).
This has nothing to do with OOP principles, which originally never included the concept of a pure interface anyway.