Activate on Non-Windows Platforms

On non-Windows platforms, you need to create call-out stub files, which are intermediate layers of C code.

The activate example in Call-Out Using activate is specific for Windows platforms.

On Windows, Uniface pushes parameters directly onto the stack, and then dynamically loads and calls the 3GL function. So, there is no need for any intermediate code.

While dynamic loading and calling is possible on all platforms supported by Uniface, pushing parameters onto the stack is not possible (or is hard to implement) on other platforms. We have therefore chosen to use a static call mechanism using stub code that takes care of the correct passing of parameters and the correct invocation of your 3GL routine.

Note:  In earlier documents, you might also see stub code being described as skeleton code. It is a bit academic which terminology is the correct one. For sake of consistency, we will use the name stub code in this documentation.

Stub files are generated from the compiled signature descriptor. You will typically use these commands:

ide /sig signame
ide /sto /lan=C Signame

where Signame is the name of your signature.

Using stub code

The signature CONV we created earlier has an operation UPCASE of type void with one STRING parameter of type INOUT. The literal name is UPCASE. To create the stub files, enter this command:

ide /sto /lan=C conv

This command creates the files uo_conv.h (the call-out interface source file) and uo_conv.c (the call-out stub source file).

Compile the file uo_conv.c (which includes the file uo_conv.h) together with your own 3GL code, and put them into your shared library. For example, for 32-bits Sun Solaris:

cc -I3gl/include -G -o lib/acttest.so acttest.c uo_conv.c -R ./lib -lucall

The generated stub code in uo_conv.c looks like this:

long USUPCASECONV (UCTRL instCtrl,
UVOID **dummy1, UCHAR *dummy2, long *dummy3)
{
long status;
char *param1;
if (!instCtrl)
{
return UACT_FAILURE;
}
status = ugetparm(instCtrl, &param1, 1);
if (status != UACT_SUCCESS)
{
return UACT_FAILURE;
}
UPCASE (param1);
status = uputparm(instCtrl, &param1, 1);
if (status != UACT_SUCCESS)
{
return UACT_FAILURE;
}
return UACT_SUCCESS;
}

Notice that the 3GL routine UPCASE, in acttest.c, is being ‘wrapped’ in a stub function USUPCASECONV. This stub function has an interface that is independent of the parameters, so it can be called dynamically on non-Windows platforms. The calls to the service routines ugetparm and uputparm take care of passing the parameters between the stub routine and your own routine.

The name of the stub function is constructed by stringing together the prefix US (the abbreviation of Uniface Signature), the operation name UPCASE, and the signature name CONV. Note that it uses the conceptual operation name, not the literal name.

In your assignment file, use the name of the stub function rather than the actual 3GL function. So instead of:

[USER_3GL]
acttest(UPCASE)

you should have:

[USER_3GL]
acttest(USUPCASECONV)

Caution: You should not modify generated stub files. Doing so creates a potential maintenance problem, because they cannot be re-generated without losing your modifications. Uniface does not support user modifications to stub files. If you need to change something in the interface, modify the signature and re-generate the stub files.