The way 'C' functions are called in jBASE compared with Interpreted Systems.jBASE_201blk.gif


 

 

Status:

Original March '94
Rev 1 June '96

Copyright (c) 1999 TEMENOS HOLDINGS NV. All rights reserved.
All Trademarks are acknowledged and are the property of their respective companies, and are recognized as such.

Abstract

When the post-relational DBMS sales brochures tell you that C can be called from the normal BASIC code, they usually omit to inform you of the restrictions attached to implementing BASIC/ C applications in the real world. This document looks behind the sales brochure to explain why we believe jBASE is a technically cleaner approach in this area. The document will also explain why mixing C with jBC (the compiled language of jBASE), is a natural consequence of its construction, whereas calling C from BASIC languages that use pseudo-code (p-code) is difficult.

The document makes a comparison between PICK™ BASIC and jBC but note that the comparison is conceptually the same when compared to the BASIC languages of any p-code based languages. Reference to performance in this document is based upon (a) logical and technical assumption and (b) performance results supplied to jBASE Software by a third-party undertaken as part of their pre-purchase product evaluation.


Calling 'C' functions from jBASE and Advanced Pick™

Advanced Pick includes a language called Pick BASIC while jBASE includes a language called jBC, both are derivatives of Dartmouth BASIC. Pick BASIC is a p-code based interpreted language (as are Uni{*}'s BASIC languages) whereas jBC is a compiled language. This important difference makes it awkward for the p-code language to interface with other UNIX/Windows compiled languages such as 'C'. These notes describe the different approaches for calling external functions written in 'C': the interpreted BASIC method and jBC; so if sales patter includes comments like "our language can call C"; say "good for you, but how does it really work?"

The approach taken by the two methods varies mainly due to the architecture of the development environment. The jBC program will be converted into 'C' source code during an intermediate compilation phase, whereas other BASIC's will generate p-code that has later to be interpreted by a run-time system, or the Pick monitor as it is called by Pick Systems.

Let use an example of writing a very simple program that calls an external 'C' function. The 'C' function will generate a hash value (a pseudo-random integer) based on the string.

The calling source code.

The jBC code in jBASE would be something like this :

DEFC INT CalculateHash(INT , VAR)
PRINT "Enter Group Size " :

INPUT GroupSize
PRINT "Enter Hash String " :
INPUT HashString
PRINT "Group the string hashes into is " : CalculateHash(GroupSize , HashString)

The Pick BASIC code would be something like this :

PRINT "Enter Group Size " :
INPUT GroupSize
GroupSize = GroupSize + 0
PRINT "Enter Hash String " :

INPUT HashString
Hash = CalculateHash(GroupSize , HashSize)
PRINT "Group the string hashes into is " : Hash

Note the main difference between the sources is that the jBASE code has function prototyping, similar to ANSI 'C'. This means that the statement;

DEFC INT CalculateHash(INT , VAR)

tells the compiler something about the CalculateHash function. Firstly it tells the compiler that when it sees CalculateHash it is a function call, rather that a dimensioned array. Secondly, it informs the compiler how many parameters are expected and what the parameter types are. This has the advantage of spotting any coding errors where the function is called incorrectly and performing type conversion automatically.

As the Pick BASIC compiler doesn't have any function prototypes, not only can you get the dreaded 'segmentation violation' if your C function is called incorrectly, but it doesn't know what types the function is expecting, so you need the following code to force the 'GroupSize' variable to be an integer with:

GroupSize = GroupSize + 0

The 'C' function source code.

Next, lets look at the 'C' code needed to support these calls. Firstly, in jBASE it would look like this :

#include <jsystem.h> 
int CalculateHash(int GroupSize , VAR * Variable)
    {
	char *p1 = (char*)CONV_SFB(Variable);
	unsigned hashvalue = 0;
while(*p1 != NULL) 
{
		hashvalue = (hashvalue << 4) + *p1++;
	}
	return (int) (hashvalue%GroupSize);
    }

Secondly, for use with Advanced Pick it might/would have to look something like this :

#include <stdio.h>
CalculateHash(GroupSize , Variable)
int GroupSize; 
char *Variable ;
{
	unsigned hashvalue = 0;
	while(*Variable != NULL)
	{
		hashvalue = (hashvalue << 4) + *Variable++;
	}
	return (int) (hashvalue%GroupSize);
}

In the Pick implementation the parameter passed is directly a null terminated string. jBASE on the other hand passed the address of the variable, and the following line of code will do the type conversion between a variable and a null terminated string:

char *p1 = (char*)CONV_SFB(Variable);

This has added 1 line of code in the jBASE 'C' function, but makes it far more flexible in that you can directly access and manipulate variables in the callers program with macros supplied with jBASE.


Compilation Process.

Thirdly, let us look how the two sources are combined to create a working program. Under jBASE, the source code would be compiled and placed in a library in the following manner :

jbc calculatehash.c -Jalibsubs.a

Any programs that want to access this 'C' function can do so just by specifying 'libsubs.a' during the compilation process. i.e. the 'C' function is only linked to the programs that need it, just like a raw C program developed outside jBASE. You could also produce a shared object version of this library.

For Advance Pick users, the function needs to be added to the Advanced Pick monitor (note: this is also true for the Uni{*} methods of calling C, in that the C functions have to be linked and become part of the environment in which they run). In a nut shell this means logging to the DM account in Advanced Pick, using the 'addbi' command to tell Advanced Pick about the 'C' function, compiling the function and re-linking a new version of the Advanced Pick monitor.

Performance

The performance of calling 'C' functions in jBC is significantly faster than in Pick BASIC (and all other BASIC versions on the market). This is partly because a call in jBC is compiled as a direct function call, as quick as any other UNIX function call. Advanced Pick on the other hand requires a search through the Advanced Pick monitor code, looking for a match on function name prior to executing it. The same 'search concept' is true of the other p-code based versions of BASIC.

Further Speed advantages

Under jBASE, the 'C' function can be put in a UNIX shared library. This means that if you change the code, then it automatically gets updated in all the calling programs without any more compilations. Under Advanced Pick, you have to rebuild the Advanced Pick monitor code every time you change a 'C' function.

When releasing an application, the jBASE application will contain all the 'C' functions as an integral part of the application. The Advanced Pick user will need to release both the 'p-code' part of the application and the objects for the 'C' function. At installation time, the end-user will need to load Advanced Pick, the p-code application, the 'C' objects and re-build the Advanced Pick monitor.

In summary not only is the jBC implementation cleaner, faster and as interoperable as the C language itself (because it is a native UNIX language), there are areas where:

  1. jBC can be made to execute even faster and
  2. The application improvements are virtually limitless.

According to extensive third-party pre-purchase evaluations of jBC, jBC is the fastest BASIC like language on the market including those with flashy names!