API Development Kit Version: 5.1

API Compatibility

Summary: This document discusses issues related to add-on compatibility.

  1. Introduction
  2. API compatibility
    1. Interface
    2. Library

0. Introduction

For a good summary on (C++) compatibility, see this page from the KDE site. We'll use the terms binary and source compatible the way they were defined on that page. The first type is superior (and of course, more valuable) from the developer's point of view, as this doesn't require any work from your side.

With the introduction of ArchiCAD 8, the previous binary add-ons compatibility was lost (i.e. ArchiCAD's ability to load and run add-ons compiled for previous versions -- namely, version 6.0, 6.5 and 7.0). On one hand, this was due to the modernization of the registration mechanisms, and on the other hand due to the enormous effort which this kind of compatibility would have required.

Between ArchiCAD 8 and 8.1 we do not ensure binary compatibility because of the interface changes of several modules (such as GSModeler, InputOutput), that is why add-ons compiled with 4.x DevKits cannot be loaded in ArchiCAD 8.1. The add-ons developed for ArchiCAD 8 must be re-compiled with this DevKit in order to enable them to run with ArchiCAD 8.1.

This document explains what compatibility means from the add-on developer's point, and what you can do about it.


1. API compatibility

Below we'll take a look at the different areas of the API where this may be an issue.

1.a Interface

By definition, an interface to a library can fulfill only source level compatibility. This means that the functionality of the API can only be extended with new functions, and the old functions shouldn't change.

The API (by itself) provides only a C interface (we have to admit this in not really true any more with ArchiCAD 8). This C interface is easier to keep source and binary compatible, because the different compilers generate the same code for the same interface. Also, the ACAP_STAT.lib contains a function table, where we left many places for the introduction of new functions.

If an old function is not relevant any more, then it should still sit there and mimic the behavior it provided in previous versions. This may require serious internal programming effort, as we would have to implement the old functionality internally over a newer set of internal interfaces. If the old functionality is still viable, just requires extra parameters to provide the functionality available in the actual version of ArchiCAD, then we can introduce a new function (much like the ...Ex functions in the Windows platform SDK). In the C interface, in the past we used the filler places in the function table to store the addresses of these functions.

In the C++ world, the (virtual) function table is generated by the compiler, and no filler 'place' exists. So, if we introduce a new function in this interface, then all code linked to this C++ library would suddenly become unusable, and your add-on would not be loaded by ArchiCAD.

Recommendation: stick to the C interface if you want to stay binary compatible. This also applies to other modules, especially to the InputOutput library, which is purely C++, except for its CIO (Compatible IO) interface, or to the file/folder dialogs in the DG module. There are certain places where you can't achieve this; but then expect to compile your add-on as a new (maintenance) version ArchiCAD reaches your market.

1.b Library

The API Development Kit contains two versions of the API library, ACAP_STAT.lib and ACAP_DLL.apx. In most cases you link your code to the static library, which provides the main entry points to the add-on (DLL/shared library), and builds of an internal function table where it stores all the addresses of the available functions. This static library also provides a version number for the API interface of ArchiCAD, which can be used internally to provide the expected behavior of the application for an add-on (i.e. an add-on compiled with the R1/v1 version of ACAP_STAT.lib (in API DevKit 4.1) can expect the behavior of ArchiCAD 8 R1/v1, even if it runs within ArchiCAD 8 R2/v2).

The other version enables you to do the initialization yourself. This way you can build up your own function table, and you also have more control over the initialization and termination of your DLL. This is the easiest way to stay binary compatible with the API itself, though it requires a lot more work from your side. The only drawback that it is available on Windows at the moment.

A very important point in the version controlling process is the CheckEnvironment function:

// -----------------------------------------------------------------------------
// Dependency definitions
// -----------------------------------------------------------------------------
API_AddonType    __ACENV_CALL    CheckEnvironment (API_EnvirParams* envir)
{
    // for tool-type add-ons: skip if not in ArchiCAD
    if (envir->serverInfo.serverApplication != APIAppl_ArchiCADID)
        return APIAddon_DontRegister;

    GSResModule saveResModule = ACAPI_UseOwnResModule ();
    ACAPI_Resource_GetLocStr (envir->addOnInfo.name, 32000, 1);
    ACAPI_Resource_GetLocStr (envir->addOnInfo.description, 32000, 2);
    ACAPI_ResetResModule (saveResModule);

    return APIAddon_Normal;
}        // CheckEnvironment

The API_EnvirParams structure contains the main and the maintenance version of the server application. Based on this information your add-on can decide whether it wants to run in the current server application. For example, a bug has been corrected in the R2/v2 version of ArchiCAD 8.1, which prevented the operation of your add-on in R1/v1. In this case you can test the server application's version in the CheckEnvironment () function, and return APIAddon_DontRegister if envir->serverInfo.releaseVersion < 2.

width=31 Copyright © 2003 - Graphisoft R&D Software Development Rt. All rights reserved worldwide.
Built on August 22, 2003