Archicad 28 C++ API
Loading...
Searching...
No Matches
Control the Load/Unload Mechanism

Remember that every add-on is a DLL on Windows and a bundle on the Macintosh. If the user invokes any of the add-on commands, the add-on is loaded into memory, then the appropriate command is executed, and finally, the add-on is purged from the memory.

The default calling mechanism

  • the add-on Manager loads the add-on, and
  • calls its CheckEnvironment function, then
  • calls its RegisterInterface function
  • the add-on is unloaded if it doesn't have to be preloaded/kept in memory

Loading add-ons on user request

  • the add-on is loaded into the memory if necessary
  • the Initialize function is called
  • the appropriate handler function is called
  • the FreeData function is called
  • the add-on is unloaded if doesn't have to be kept in memory

This default scheme is quite inconvenient if the functionality needs a complex initialization/termination procedure. Suppose that an add-on is working on an external database too. If the user needs any information stored in that database, first it must be initialized, then the links must be set up to the Archicad database. It can take a significant amount of time.

A better solution can be if the add-on can initialize itself only once, no matter how many user commands are invoked. Of course, it can be implemented if your add-on is kept in the memory between several user interactions only. This is the only way to preserve the initialized global variables, dynamic memory blocks, etc.

The solution is to call the ACAPI_KeepInMemory function, while any of the handler functions are executed. Some operations (e.g. when an add-on has its palette, or registers a notification handler) cause the add-on to stay in memory without calling this function.

In this case, the add-on will NOT be UNLOADED from the memory upon return from the callback function. The add-on remains loaded, which means that the FreeData function will not be called, of course. In this case, it is not necessary to load the add-on into the memory upon the next user request, so the Initialize function will not be called also that time. The server application keeps calling the registered callback function(s) only.

The rules are very easy:

  • the Initialize function is called just after the add-on is loaded into the memory physically,
  • the appropriate callback function is called when the Initialize function has been executed and returns successfully,
  • the FreeData function is called just before the add-on must be swapped out.
    An add-on must be unloaded when the last handler function has not called the ACAPI_KeepInMemory function, all the palettes have been dismissed, and all the registered notification handlers have been unregistered.

Note: if you have global variables, they will be initialized each time the add-on is loaded, and destroyed each time the add-on is unloaded. This may mean three initialization and termination sequences for a simple add-on command. This can have a severe impact on your add-on's performance and on the startup time of the server application, especially if you have instances of complex C++ classes as global variables. Also, the API (and most other modules') services are not available during the construction and destruction of these global variables, so e.g. you cannot use the BM Memory Manager there. This leads to nice crashes in the past; the solution is to use only pointers and construct the global instances only in your initialize function.

The controlled calling mechanism

According to the above rules you can prevent yourself from unloading from the memory by the server application.

  • user request
  • the add-on is loaded into the memory
    • Initialize is called
    • a handler function is called
      • ACAPI_KeepInMemory called by the add-on
  • user request
    • a handler function is called
      • ACAPI_KeepInMemory called by the add-on
  • user request
    • a handler function is called
      • ACAPI_KeepInMemory called by the add-on
  • user request
    • a handler function is called
    • FreeData is called
  • the add-on is unloaded

Important

You may have serious problems if you use this feature without enough care.

An example: You initialize your data structure according to the actual Archicad database. Your code is kept in the memory, but between two commands the user opens another Archicad project, or closes the active one, etc. In such cases, your initialization process may fail because the add-on still stores data from the previous project.

To control these events, you must handle the notification codes sent by Archicad. They are documented in the Notification Manager. By tracking these notification codes, you will be informed by Archicad if the user opens a new project, closes the active one, creates a completely new one, or even if the user quits Archicad.