
For interoperability with other development tools (or applications created with them), conzept 16 provides a general interface: the external programming interface. Like the other components, this is included in the setup of conzept 16 in the form of a DLL and can be installed separately.
Introduction
The conzept 16 programming interface is supplied as a dynamic link library in three variants:
- Programming interface (c16_pgxw.dll / 32-bit)
This DLL provides access to the data structure and user information as well as functions for data record processing. In addition, functions for accessing internal database texts are available and procedures can be executed. - Programming interface (c16_pgx_w64.dll / 64-bit)
Like the first variant, but for use in 64-bit applications. - Extended programming interface (c16_pgxe.dll)
This DLL also offers the option of executing procedures that contain interface commands (e.g. WinDialog). In order for the library to be loaded, further DLLs must be available (e.g. c16_objw.dll).
Integrating the programming interface into existing C or C++ projects is very easy thanks to the supplied header files (c16.h, c16_pgx.h) and the link libraries. This article shows how the DLL can be used in an application that was developed with Visual C#.
Visual C#
Although the C# language is very similar to C++, the C header files provided by conzept 16 cannot be used here. The same applies to the link libraries. Therefore, a way must first be found to use the functions provided by the DLL. Fortunately, Visual C# also offers the possibility of interoperability. The starting point is the namespace ‘System.Runtime.InteropServices’, which also provides methods for the use of DLLs that were not created with C#.
Functions
C# offers the DllImportAttribute class for integrating functions from external DLLs.
[DllImport("c16_pgxw.dll")]
public static extern Int32 C16_InitPgif(Int32 memoryLimit, ref IntPtr pgifHdl);
The statement imports the function C16_InitPgif from the DLL “c16_pgxw.dll” and defines that it has two arguments (memoryLimit and pgifHdl). The order and type of the arguments must be identical to the function declaration (c16_pgx.h) defined by concept 16 (see code snippet below).
/* initialize interface module */
C16API C16_InitPgif
(
const vLONG aMemoryLimit, /* in: upper memory limit */
vPHANDLE* aPgifHdl /* out: module handle */
);
The type vLONG defined by conzept 16 represents a signed 32-bit integer. The equivalent in C# is Int32. The second argument (aPgifHdl) returns a value of type vPHANDLE. The data type IntPtr can be used for this in C#. It is important that the argument is declared as ‘ref’ so that it is clear that the function returns a value.
Structures
In many functions of the programming interface, pointers to structures are passed. The following code snippet shows the declaration of the function C16_QueryPgifInfo, which returns information on the programming interface.
/* query interface informations */
C16API C16_QueryPgifInfo
(
const vPHANDLE aPgifHdl, /* in: module handle */
vC16_PgifInfo* aInfoBlock /* out: information block */
);
The second argument provides a pointer to a structure of type vC16_PgifInfo. The structure is defined in the header file c16.h as follows.
/* interface information structure */
typedef struct
{
vINT InfoSize; /* size of information block */
vINT PgifType; /* type of interface */
vCHAR PgifLicense[20]; /* license number */
vCHAR PgifRelease[8]; /* release info */
vINT PgifUserLimit; /* user limit */
vINT PgifMemory; /* current allocated memory */
vINT PgifMemoryPeak; /* peak allocated memory */
}
vC16_PgifInfo;
The structure must be ported to C# so that the function can be called from C#.
[StructLayout(LayoutKind.Explicit)]
public struct PgifInfo
{
[FieldOffset(0)]
public UInt32 InfoSize;
[FieldOffset(4)]
public UInt32 PgifType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
[FieldOffset(8)]
public Byte[] PgifLicense;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
[FieldOffset(28)]
public Byte[] PgifRelease;
[FieldOffset(36)]
public UInt32 PgifUserLimit;
[FieldOffset(40)]
public UInt32 PgifMemory;
[FieldOffset(44)]
public UInt32 PgifMemoryPeak;
}
The structure is declared in C# using ‘public struct PgifInfo’. The layout plays a decisive role here. This defines at which byte offset the individual members of the structure are located. LayoutKind.Explicit’ specifies that each individual field offset is defined explicitly. This is done by specifying ‘FieldOffset’ before the corresponding member. InfoSize is in the first position in the structure and therefore has the field offset 0. As InfoSize is of type vINT (UInt32 in C#) and therefore 4 bytes in size, the member PgifType starts at offset 4, etc.
The sample application
The sample application ‘ApiDemo’ was developed in Microsoft Visual Studio 2013. The archive at the end of the article contains the Visual Studio project including source code and executable application. Once the ‘ApiDemo.sln’ project has been opened in Visual Studio, the example can be executed using the F5 function key.
A database connection can be established or disconnected via the ‘Connection’ menu item in the application’s main menu. The output area is divided into two pages. The ‘General’ page shows information on the programming interface used, the database and the connected database server. The ‘Data structure’ page shows all the files in the selected database. Double-clicking on a file icon lists the partial data records, keys and links. You can switch to the higher level by clicking the arrow button.
Conclusion
The programming interface was specially developed for use in heterogeneous application structures. For existing applications that were not or only partially developed with conzept 16, the interface offers a universal way of connecting to a conzept 16 database.