ACAPI_​Command_​ExternalCall

Call a command of an other add-on in another ARCHICAD instance.

    GSErrCode  ACAPI_Command_ExternalCall (
        const IO::Location*          projectFileLoc,
        const API_ModulID*           mdid,
        GSType                       cmdID,
        Int32                        cmdVersion,
        GSHandle                     params,
        bool                         silentMode,
        APIExternalCallBackProc*     externalCallbackProc
    );

 

Parameters

projectFileLoc
[in] the location of the project file to be opened during the remote call
mdid
[in] the identifier of the target add-on. It is defined by the ‘MDID’ resource
cmdID
[in] the identifier of the command to be executed
cmdVersion
[in] the required command version
params
[in/out] passed parameters (optional). See the Inter-add-on communication section of the ACAPI_Goodies functions
silentMode
[in] instruct the target add-on to work in silent mode. No option dialogs, error alerts …etc.
externalCallbackProc
[in] optional callback procedure for handling the responses asynchronously

 

Return Values

NoError
the function completed successfully
APIERR_BADPARS
the mdid or the projectFileLoc parameter is nullptr
APIERR_REFUSEDPAR
the location defined by projectFileLoc is empty or invalid
APIERR_MODULNOTINSTALLED
the referenced add-on is not installed
APIERR_MODULCMDNOTSUPPORTED
the referenced command is not supported by the target add-on
APIERR_MODULCMDVERSNOTSUPPORTED
the requested command version is too new; not supported by the target add-on
APIERR_CANCEL
the external operation has been canceled (either by the user or due to communication problem)

For other common errors see the list of error codes.

 

Remarks

This function is used to call an add-on implemented command on a different plan loaded into another instance of ARCHICAD.

The system provides that the requested project would be available for performing the command in the following way:

  • if there is already an ARCHICAD application running with the specified plan, it attempts to reserve it for the external call (it waits for the application to be available if currently busy with some other operation)
  • if there is an ARCHICAD running with currently no plan opened in it (empty), it reserves that application and makes it load the project file
  • if there is no available ARCHICAD running, it launches a new application instance with loading the requested project file

After the external ARCHICAD instance is reserved for serving the add-on command call, the operation works similarly to the ACAPI_Command_Call function. On the server side the callee add-on does not even realize that the command request comes from another application instance. The only difference is that the resultData parameter is always nullptr when calling its APIModulCommandProc handler, because this pointer cannot be passed between ARCHICADs. However you can change the content of the params handle modifying any parameters to communicate the result to the caller.

The caller can decide the function to return immediately after sending the command request (asynchronous operation) or to wait for the external call to be finished (synchronous operation). You need to pass an APIExternalCallBackProc handler function to collect the responses asynchronously; if this parameter is nullptr, the function does not return until the external operation is finished. The advantage of the asynchronous way is that you can initiate more calls even with different project files at the same time, and the internal task scheduler will optimize the sequence of execution.

Please note that if you use a loop for waiting for the asynchronous responses, do not reserve the processor time superfluously, let other threads run by calling the TIWait function of the GSRoot module.

Refer to the Communication Manager for more detailed description on

  • how to pass parameters
  • how to get return values
  • how the heaps and API environments are managed by the API

 

Example

The following sample exports the elements of the example project into a specified DWG file by calling the standard DXF/DWG add-on synchronously in an external ARCHICAD:


API_ModulID mdid = { 1198731108, 1322668197 };  // MDID of the DXF/DWG add-on

IO::Location projectFileLoc;
API_SpecFolderID specFolderID = API_ApplicationFolderID;
ACAPI_Environment (APIEnv_GetSpecFolderID, &specFolderID, &projectFileLoc);
projectFileLoc.AppendToLocal ("ARCHICAD Examples");
projectFileLoc.AppendToLocal ("Residential House");
projectFileLoc.AppendToLocal ("Residential House.pla");

IO::Location outputLoc;
specFolderID = API_UserDocumentsFolderID;
ACAPI_Environment (APIEnv_GetSpecFolderID, &specFolderID, &outputLoc);
outputLoc.AppendToLocal ("Residential House.DWG");

IO::Location configFile;                        // translator to be applied for this output
specFolderID = API_DefaultsFolderID;
ACAPI_Environment (APIEnv_GetSpecFolderID, &specFolderID, &configFile);
configFile.AppendToLocal ("DXF-DWG Translators");
configFile.AppendToLocal ("For as is output.Xml");

GSHandle parHdl = nullptr;                         // handle of command call parameters

GSErrCode err = ACAPI_Goodies (APIAny_InitMDCLParameterListID, &parHdl, nullptr);
if (err == NoError) {
    API_MDCLParameter par;                      // parameter describing the output file
    char str[512];
    IO::URL url;

    BNZeroMemory (&par, sizeof (API_MDCLParameter));
    par.name = "FileName";
    par.type = MDCLPar_string;
    outputLoc.ToURL (&url);
    CHTruncate ((const char*) url, str, sizeof (str));
    par.string_par = str;
    err = ACAPI_Goodies (APIAny_AddMDCLParameterID, parHdl, &par);

    if (err == NoError) {
        BNZeroMemory (&par, sizeof (API_MDCLParameter));
        par.name = "ConfigFile";
        par.type = MDCLPar_string;
        configFile.ToURL (&url);
        CHTruncate ((const char*) url, str, sizeof (str));
        par.string_par = str;
        err = ACAPI_Goodies (APIAny_AddMDCLParameterID, parHdl, &par);
    }

    if (err == NoError) {
        err = ACAPI_Command_ExternalCall (&projectFileLoc, &mdid, 'SAV2', 1, parHdl, true, nullptr);
        if (err != NoError) {
            DBPrintf ("DXF/DWG export %s\n", (err == APIERR_CANCEL) ? "canceled" : "failed");
        }
    }

    ACAPI_Goodies (APIAny_FreeMDCLParameterListID, &parHdl, nullptr);
}

 

Please also check the Communication Manager example add-on for an asynchronous external module call sample.

 

Requirements

Version: API 10 or later
Header: ACAPinc.h

 

See Also

API_ModulID, ‘MDID’
APIExternalCallBackProc
APIModulCommandProc
ACAPI_Command_Call
ACAPI_Command_Test
Communication Manager
API Functions