Admin Production ni-theme
Current Publication

Generated ActiveX Server Files and Code

LabWindows/CVI

Generated ActiveX Server Files and Code

When you click the Save and Generate button in the Edit ActiveX Server tool, LabWindows/CVI saves the changes in the specification file and generates the ActiveX code in the target header, source, and IDL files. Use the LabWindows/CVI ActiveX Library functions in conjunction with the generated code to implement an ActiveX server. Do not make changes to the generated code because the ActiveX Server tools overwrite the target files when the tools generate code and reinitialize target files. If you need to make changes to the generated code, make new copies of the target files and make changes in the new files and not the target files. You can open the generated source, include, and IDL files using the LabWindows/CVI source editor. Double-clicking the specification (.axs) file opens the Edit ActiveX Server tool. LabWindows/CVI generates the following files:

Include File (MyServer_axs.h)

  • Feature function prototypes—LabWindows/CVI generates prototypes for functions in which you must implement the functionality of the server. You must implement the feature functions in your source files. These functions are called from the interface member functions in the generated source file. Refer to the Source File section for more information about the role of the interface member functions. The following code demonstrates the feature function for the Add method in the ICalc interface implemented by MyObj:

    HRESULT CVIFUNC MyObjICalcAdd (CAServerObjHandle objHandle, short n1, short n2, short* sum)
    {
       if (sum == NULL) {
          return E_INVALIDARG; // invalid argument
       }
       else {
          *sum = n1 + n2;
          return S_OK;
       }
    }
  • Event wrapper functions—LabWindows/CVI generates helper functions that you can call to fire events registered by your ActiveX objects. Sample use of these functions also is generated in the header file as comments.
  • Callback functions
    • Server callback function—The prototype of the server callback function is generated in the include file. You must implement this function in your source code. The LabWindows/CVI ActiveX Library calls this callback function with the CA_SERVER_EVENT_MODULE_EXIT event. This event occurs when an EXE server is ready to exit, which is when all references to ActiveX objects in the server have been released. You can prevent the server from shutting down by returning a nonzero value from this function. The server callback function is available only for EXE servers. The following code is a sample server callback function:

      // Example Server callback function
      int CVIFUNC ServerCb (int event)
      {
         HRESULT hr = S_OK;

         if (event == CA_SERVER_EVENT_MODULE_EXIT) {
            // Uninitialize and cleanup the server
         }
         return hr;
      }
    • Object callback functions—The prototypes of the object callback functions are generated in the include file. You must implement these functions in your source code. These callback functions are called with the CA_SERVER_EVENT_OBJECT_CREATE and CA_SERVER_EVENT_OBJECT_DESTROY events. The CA_SERVER_EVENT_OBJECT_CREATE event occurs when an object is being created. When this event occurs, the callbackData passed to this function is the IUnknown pointer of the object. You can use this pointer to aggregate other objects. The object is not created if the return value of the callback function indicates failure. You must return a value indicating success for the object to be created. The CA_SERVER_EVENT_OBJECT_DESTROY event occurs when an object is being destroyed. For this event, the callbackData parameter will be NULL, and LabWindows/CVI ignores the return value of the function. The following code is a sample object callback function.

      // Example object callback function
      HRESULT CVIFUNC SrvrObjCb (CAServerObjHandle objHandle, const CLSID *pClsid, int event, void *callbackData)
      {
         HRESULT hr = S_OK;
         if (event == CA_SERVER_EVENT_OBJECT_CREATE) {
            // Initialize object state
         }

         else if (event == CA_SERVER_EVENT_OBJECT_DESTROY) {
            // Uninitialize object state and cleanup
         }
         return hr;
      }
  • Init and Uninit function prototypes—These functions initialize and uninitialize the ActiveX server and must be called in the main function of the server (WinMain for EXE servers and DllMain for DLL servers). These functions are implemented in the generated source file. Refer to the comments in the generated code for help about using these functions. You can use the generated example as a template. The following code is a sample WinMain (for EXE servers):

    int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
    lpszCmdLine, int nCmdShow)
    {
       int runServer = 0;
       char errBuf [500] = {0};

       if (InitCVIRTE (hInstance, 0, 0) == 0)
          return -1; // Out of memory
       // ActiveX server initialization
       if (FAILED (MyServerInit (hInstance, lpszCmdLine, &runServer, errBuf, sizeof(errBuf))))
             return -1;// Server initialization error
       if (runServer)
          {
          // ...
          // Your initialization code
          // ...

          RunUserInterface (); // Process messages

          // ...
          // Your cleanup code
          // ...
    }
       // ActiveX server cleanup
       MyServerUninit (hInstance);
       return 0;
    }

    The following code is a sample DllMain (for DLL servers):

    int __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
       char errBuf [500] = {0};

       switch (fdwReason)
          {
          case DLL_PROCESS_ATTACH:
             if (InitCVIRTE (hinstDLL, 0, 0) == 0)
                return 0; // out of memory
             // ActiveX server initialization
             if (FAILED (MyServerInit (hinstDLL, errBuf, sizeof(errBuf))))
                return 0; // Server initialization error
             break;
          case DLL_PROCESS_DETACH:
             // ActiveX server cleanup
             MyServerUninit (hinstDLL);
             CloseCVIRTE ();
             break;
          }
       return 1;
    }
  • ActiveX Interface definitions—The definitions for the ActiveX interfaces specified in the server are generated in the target include file. You can define and use interface pointers like other C pointers.
  • GUIDs—The GUIDs (IIDs, CLSIDs, and LIBID) specified in the server are defined in the generated source file and declared in the generated header file.

Source File (MyServer_axs.c)

  • GUIDs—The specified GUIDs (IIDs, CLSIDs, and LIBID) are defined in this file.
  • ActiveX interface member functions—The definitions of functions that represent the methods and properties in the ActiveX interfaces are generated in the target source file. These functions call the feature functions that you implement. The addresses of these ActiveX functions are stored in the ActiveX interfaces; therefore, these functions are referred to as interface members. For example, the following code demonstrates the interface member function for the Add method in the ICalc interface implemented by MyObj.
    static STDMETHODIMP CaSrvrMyObjICalcAdd (ICalc* This, short n1, short n2, short* sum)
    {
       CAServerObjHandle objHandle = 0;
       HRESULT __result = 0;

       __caErrChk (CA_ServerGetObjHandleFromIface (This, &objHandle));
       __caErrChk (MyObjICalcAdd (objHandle, n1, n2, sum));

    Error:    return __result; }

    ActiveX interface member functions differ from feature functions in the following aspects:
    • The first parameter of the interface member functions is a pointer to the interface. The first parameter of the feature functions is a variable of type CAServerObjHandle and identifies the object associated with the interface.
    • The data types of interface member function parameters are ActiveX Automation types, whereas the data types of feature function parameters are equivalent C data types (except for VARIANT, because it is not possible to determine the actual data type present in the VARIANT at compile time).
    • The interface member functions convert ActiveX Automation types to equivalent C data types before calling the corresponding feature functions and then reconvert the returned C data types to ActiveX Automation data types before returning to the client.
  • Event wrapper function definitions—The definitions of the event wrapper functions, if any, are generated in this section. You must call these functions to fire the corresponding events from ActiveX objects.
  • Data structures—A number of structures are generated to represent the ActiveX server configuration. The types of these structures are defined in the cviauto.h include file. The LabWindows/CVI ActiveX Library uses these structures to provide the COM functionality at run time.
  • Init and Uninit functions—The definitions of the Init and Uninit functions that initialize and uninitialize the ActiveX server are generated in the source file. These functions call the CA_InitActiveXServer and CA_CloseActiveXServer functions in the LabWindows/CVI ActiveX Library. Refer to the sample code generated in the target header file for the recommended use of these functions.

IDL File (MyServer_axs.idl)

  • IDL code—This file contains the IDL code to build the type library. LabWindows/CVI compiles the type library and embeds it in the target DLL or EXE when you build the ActiveX server.