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:
- It must implement the following 4 methods:
- dll_main – Main entry of the plug-in. The first three parameters are string parameters that can be used by the plug-ins in different ways. A normal usage pattern for these parameters is to use them for repository, model and method name. Repository and model name is used to open the target model. The method name can be used as a switch within dll_main to execute the correct sub-method. Dll_main must also have other input parameters that are transferred from the client program to the plug-in, and return values that are transferred back to calling client program. Details will be explained later.
- dll_version – Must return a 64 bits integer as the version number.
- dll_malloc – method for allocating memory in the plug-in.
- dll_freeAll – method called by EDM application server when all return values are sent back to the calling client program.
- If it shall access the EDM database, it must be linked with EDM database access library appserver600.lib.
- A plug-in method is invoked within an EDM application server by a client program executing the edmi method edmiRemoteExecuteCppMethod.
- Input parameters and return values shall be "packed" into an object with class name CppParameterClass for easy transfer between the client program and the EDM application server.
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 {
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 (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.
Table 2: EDMparameter types
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);