The EDM Server Side C++ Plug-ins are C++ programs that will be built as a dynamically linked libraries (.dll on Windows, .so on Linux). Such plugins will read and write to/from an EDM data model as if they were stand-alone programs that open the database exclusively. Such database access will be very efficient. Such plug-ins (.dll modules) shall be linked into the address space of the EDM application server on demand when the first call to a method in a plug-in .dll is executed.
An EDM plug-in has the following characteristics:
...
In the following we will describe how to implement a method that shall run as an EDM server side plug-in. Since input parameters are transferred from a client program to the EDM application server, and return values are transferred back to client program, we will explain in detail how this is done. To illustrate this functionality we make use of an example from the finite element analysis world. The server side method shall return info about meshes from an analysis done for one specific time steps – GetListOfMeshes. Input parameters to GetListOfMeshes are repositoryName, modelName, analysisID and timeStep. Return values are two strings and a list of records where each record holds information about one mesh. MeshInfo is defined below:
struct MeshInfo {
char name[MAX_NAME_SIZE];
EDMULONG n_vertices;
EDMULONG n_elements;
} MeshInfo;
To implement a call to the server method GetListOfMeshes one must perform the following steps:
Generic input parameters serverContextId , remoteRepositoryName, remoteModelName , pluginPath, pluginNameand methodName are the first six parameters of edmiRemoteExecuteCppMethod. The two other input parameters, analysisID and timeStep, are specific for the GetListOfMeshes method and must be transferred to the server within a parameter container InGetListOfMeshes, which is declared below.
Declare container for input parameters InGetListOfMeshes as subclass of CppParameterClass
class InGetListOfMeshes : public PlugnParameter PluginParameter {
cppRemoteParameter *attrPointerArr[2]; // the size, [2], must be equal to number of consecutive parameters.
cppRemoteParameter *analysisID;
cppRemoteParameter *timeStep;
void* operator new(size_t sz, CMemoryAllocator *ma){ return ma->alloc(sz); }
InGetListOfMeshes(CMemoryAllocator *_ma, cppRemoteParameter *inAttrPointerArr) : PlugnParameter PluginParameter (attrPointerArr, sizeof(attrPointerArr), _ma, inAttrPointerArr) {
addAttribute(&analysisID, rptSTRING);
addAttribute(&timeStep, rptREAL);
}
};
Each parameter must be declared as pointer attributes to the subclass of CppParameterClass. It is also required that a cppRemoteParameter pointer array with size equal to number of parameters. This pointer array is the pointer array that is used as parameter to edmiRemoteExecuteCppMethod
In the constructor addAttribute must be called for each parameter:
addAttribute(&analysisID, rptSTRING);
addAttribute(&timeStep, rptREAL);
The second parameter to addAttribute is the type of the attribute. EDM supports the types of parameters listed in Table 2, below.
...
Parameter types | Explanation |
---|---|
rptINTEGER, rptREAL, rptBOOLEAN, rptLOGICAL, rptSTRING, rptENUMERATION | EDM primitive types |
rptAggrINTEGER, rptAggrREAL, | Array of 64 bits integer or real |
rptLongAggrINTEGER, rptLongAggrREAL, | Same as above - the implementation use this to specify different handling. |
rptBLOB | Continuous array of bytes |
rptContainer | template <class ContainerMember> |
rptStringContainer | Special implementation of string container: |
rptCMemoryAllocator | All memory buffers of the memory allocator are transferred as one parameter. There are methods to support relocation of pointers after transfer of the memory buffers to target process. Explained in code examples below. |
rptUndefined | Empty / undefined parameter. |
The return values container has the following return values attributes:
cppRemoteParameter *status;
cppRemoteParameter *report;
cppRemoteParameter *mesh_info_list;
and within the constructor the initialization is as follows:
addAddribute(&status, rptSTRING);
addAddribute(&report, rptSTRING);
addAddribute(&mesh_info_list, rptContainer);