Example for building a C-API project Foundation
This section demonstrates how to use the C-API within your projects. An example is discussed in detail showing the different steps required to compile your C-sources and link them to an Xbase++ application.
Make sure you have installed the Xbase++ C-API correctly.
The following files must be located in a directory listed in your INCLUDE-path.
xppdef.h, xppcon.h, xpppar.h
You need Microsoft Visual-C++ Version 4.0 or higher.
You need IBM VisualAge-C++ Version 3.0 or higher.
Also make sure that the directories of your C-compiler are correctly listed in the PATH, LIB and INCLUDE environment variables.
Create a makefile to build both the Xbase++ source and the C-source and link the two resulting OBJ files. The makefile includes the following instructions:
CC=cl /c /Zl /Tc
LINK=alink /DE
sample.exe: sample.obj f2bin.obj
$(LINK) sample.obj f2bin.obj
sample.obj: sample.prg
xpp /b /q $*
f2bin.obj: f2bin.c
$(CC) f2bin.c
In the example, any numeric value is converted to an 8-Byte-binary string and vice versa. The code in the file F2BIN.C looks like this:
#include <windows.h>
#include "xppdef.h"
#include "xpppar.h"
#include "xppcon.h"
#ifdef _MSC_VER
int _fltused;
#endif
#define MAXLEN 8
/* this is the "little secret":
* treat the memory of a double
* like a string with 8 bytes (and the terminating 0)
*/
typedef union {
double dbl;
char string[MAXLEN+1];
} F2BinBuffer;
/*
* Create a binary string from a numeric
*
* F2BIN(nNumber) => c8Binary
*/
XPPRET XPPENTRY F2BIN(XppParamList paramList) {
ContainerHandle chResult = _conNew(NULLCONTAINER);
F2BinBuffer valBuffer={0};
if ( XPP_IS_NUM( _partype( paramList, 1) ) ) {
valBuffer.dbl = _parnd( paramList, 1);
}
else {
// return a 0-filled buffer if any errors
valBuffer.dbl = 0.0;
}
_conPutCL( chResult, valBuffer.string, MAXLEN );
_conReturn( paramList, chResult);
_conRelease( chResult);
return;
}
/*
* reverse the binary string to a numeric
*
* BIN2F(c8Binary) => nNumber (0 if any parameter errors)
*/
XPPRET XPPENTRY BIN2F(XppParamList paramList) {
F2BinBuffer valBuffer={0};
if ( XPP_IS_CHAR( _partype( paramList, 1) ) ) {
_parc( valBuffer.string, MAXLEN+1, paramList, 1 );
}
_retnd( paramList, valBuffer.dbl);
return;
}
The C-compiler mangles __cdecl function names with a preceding underscore. Therefore, you must map the function names in your Xbase++ code to match the actual C-function names (refer to the next section for details about #pragma map). The following Xbase++ code tests the C-functions F2Bin() and Bin2F() (file SAMPLE.PRG):
#pragma map(F2BIN,"_F2BIN")
#pragma map(BIN2F,"_BIN2F")
PROCEDURE Main
LOCAL nNumber, cTemp
/* XPP_DOUBLE - Test */
nNumber := 100.234e16
? nNumber
cTemp := F2Bin(nNumber)
nNumber := Bin2F(cTemp)
? nNumber
/* XPP_NUMERIC - Test */
nNumber := 45345
? nNumber
cTemp := F2Bin(nNumber)
nNumber := Bin2F(cTemp)
? nNumber
RETURN
To build the project you enter on the command line:
make -f <name of makefile>
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.