Implement front call modules for GDC
Custom front call modules for the desktop front-end are implemented by using the API for GDC front calls in C language.
GDC custom front call basics
In order to extend the GDC with your own front calls, you must be familiar with C++ programming, and have a C++ compiler installed on your development platform.
GDC front call modules must be implemented as a Dynamic Linked Library (.DLL) on Windows® platforms, as a shared library (.so) on Linux®, or as a Dynamic Library (.dyLib) under Mac® Os X. This shared library must be deployed on each platform where the GDC front-end executes.
The GDC is able to automatically load the front call module and find the function,
based on the module name and function name used in the Genero BDL front call
(ui.Interface.frontCall
).
The API for GDC front calls is based on the frontEndInterface
front call interface structure, that is used to interface with the GDC core, in
order to pass/return values to/from a front call.
- Create a C source to implement your front call functions.
- In the front call functions body:
- Check the number of parameters passed with the
getParamCount()
function. - Pop parameter values with one of the
pop*()
functions. - Perform the function task.
- Push the result values with one of the
push*()
functions. - Return 0 on success, -1 otherwise.
- Check the number of parameters passed with the
- Compile and link the shared library.
- Deploy the shared library to the platform where GDC executes.
The front call interface structure
- manage the stack (push or pop for each handled data type)
- get information about the function (number of in and out parameters)
- get information about the front-end (front call environment variables)
struct frontEndInterface
{
short (* getParamCount) ();
short (* getReturnCount) ();
void (* popInteger) (long &, short &);
void (* pushInteger) (const long, short);
void (* popString) (char *, short &, short &);
void (* pushString) (const char *, short, short);
void (* getFrontEndEnv) (const char *, char *, short &);
void (* popWString) (wchar_t *, short &, short &);
void (* pushWString) (const wchar_t*, short, short);
};
Prototype of a front call function implementation
The prototype of each front call function must be:
int function_name ( const struct frontEndInterface &fci );
- function_name is the name of your function.
fci
is the front call interface structure.
The fci
structure will be filled in by the GDC and passed to the
custom function. You can then use this structure to pop/push values from/to the stack, and get
environment information from the core GDC.
The function must return 0 on success, -1 otherwise.
Front call environment variables
The front call function can query the GDC for front call environment variables, to get information about the context.
The following front call environment variables are supported:
Environment Variable | Description |
---|---|
frontEndPath |
The path where the GDC front-end is installed. |
Module initialization and finalization
The font-call module can define initialization and finalization functions. GDC will automatically call these functions as follows:
void initialize();
This function is called when the front call module library is loaded. If needed, perform variable initialization and resource allocation in this function.
void finalize();
This function is called when the GDC front-end stops. If needed, perform resource release in this function.
The API for custom front call implementation
Function | Description |
---|---|
|
This function returns the number of parameters given to the function called. |
|
This function returns the number of returning values of the function called. |
|
This function is used to
get context information from the front-end.
|
|
This function is used to
get an integer from the stack.
|
|
This function is used to
push an integer on the stack.
|
|
This function is used to
get a string from the stack.
|
|
This function is used to
push a string on the stack.
|
|
This function is used to
get a WideChar string from the stack.
|
|
This function is used to
push a WideChar string on the stack.
|
Calling the custom front call from BDL
In the Genero program, use the ui.Interface.frontCall()
API to call the front-end function. This method
takes the front call module name as the first parameter and the front call function name as second
parameter. The front call module name is defined by the name of the dynamic library
(module_name.DLL,
module_name.so or
module_name.dylib).
mymodule
" as front call module
name:CALL ui.Interface.frontCall("mymodule", "myfunction", ["John DOE"], [msg])
Deploying the custom front call module
The shared library implementing the custom front call functions must be deployed on the platform where the GDC executes. Copy your custom front call modules in the bin directory of the GDC installation directory (%GDCDIR%\bin).
Example
This example implements a simple front call function that computes the sum of two integer numbers. It takes two parameters and returns two values.
mymodule.h:
struct frontEndInterface
{
short (* getParamCount) ();
short (* getReturnCount) ();
void (* popInteger) (long &, short &);
void (* pushInteger) (const long, short);
void (* popString) (char *, short &, short &);
void (* pushString) (const char *, short, short);
void (* getFrontEndEnv) (const char *, char *, short &);
void (* popWString) (wchar_t *, short &, short &);
void (* pushWString) (const wchar_t*, short, short);
};
#ifdef WIN32
#define EXPORT extern "C" __declspec(dllexport)
#else
#define EXPORT extern "C"
#endif
EXPORT void initialize();
EXPORT void finalize();
EXPORT int mysum(const frontEndInterface &fx);
#include "mymodule.h"
#include <stdio.h>
#include <string.h>
void initialize() {
}
void finalize() {
}
int mysum(const struct frontEndInterface &fci) {
long param1, param2;
short isNull1, isNull2;
long sum;
char msg[255];
if (fci.getParamCount() != 2 || fci.getReturnCount() != 2) {
return -1;
}
fci.popInteger(param2, isNull2);
fci.popInteger(param1, isNull1);
sum = param1 + param2;
if (!isNull1 && !isNull2) {
sum = param1 + param2;
sprintf(msg, "%d + %d = %d", param1, param2, sum);
} else {
sum = 0;
sprintf(msg, "Parameters are NULL");
}
fci.pushInteger(sum, 0);
fci.pushString(msg, strlen(msg), 0);
return 0;
}
ui.Interface.frontCall()
method in your Genero program:
MAIN
DEFINE res INT, msg STRING
MENU
ON ACTION frontcall ATTRIBUTES(TEXT="Call custom front call")
CALL ui.Interface.frontCall("mymodule", "mysum",
[100,250], [res,msg])
DISPLAY "Result: ", res, "\n", msg
ON ACTION quit
EXIT MENU
END MENU
END MAIN