Calling DADiSP from C++

 

DADiSP’s Automation services can also be accessed from compiled languages such as C++. In this case, DADiSP provides a COM "dual" interface to allow direct "Vtbl" access to implement ActiveX commands in a manner that is more natural and faster for C++. To make full use of the dual interface, the file actx.h must be included in the C++ source file and the C file actx_i.c must be compiled and linked. Both files are available in the spl\activex release directory.

 

Function parameters are transferred using the VARIANT data type. Series and arrays are passed as SafeArrays.

 

The following code fragment demonstrates the use of the Execute and GetComplexSeries methods in C++.

 

#include <windows.h>

#include <iostream.h>

#include <objbase.h>

#include <stdio.h>

#include <stdlib.h>

#include <assert.h>

#include <strstrea.h>

#include <time.h>

#include "actx.h" // DADiSP specific header

 

/* forward declarations */

int       CstrToBstr(char *str, BSTR *pbstr);

char      *BstrToCstr(BSTR bstr);

int       strncpyfar(char *l, LPCOLESTR f, int n);

BOOL      ANSIToUnicode(PCSTR szStrA, PWSTR *pszStrW);

SAFEARRAY *DarrayToSafeArray(double *s, int nrow, int ncol);

SAFEARRAY *CreateSafeArray();

void      ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned int uiArgErr);

void      trace(char *msg);

void      DisplayVariant(VARIANT *pvar);

void      DisplayArray(SAFEARRAY *psa, int vtype);

void      CreateRandomArray(double *darray, int size);

void      CreateLinearArray(double *darray, int size);

 

/* defines */

#define ARRAY_SIZE   4

 

// array to transfer

double darray[ARRAY_SIZE*ARRAY_SIZE];

 

/* this is a console application */

int main ()

{

    SAFEARRAY *psa, *psaRe, *psaIm;

    VARIANT varResult;

    BSTR bstrIn;

    IDadisp *pIDadisp = NULL;

    int iResult, status = 0;

    HRESULT hr;

 

    hr = OleInitialize(NULL);

 

    // start DADiSP as a direct vtbl automation server

    hr = ::CoCreateInstance(CLSID_DADiSPApp, // DADiSP CLSID identifier

                        NULL,

                        CLSCTX_LOCAL_SERVER,

                        IID_IDadisp,        // DADiSPinterface

                        (void**)&pIDadisp);

 

    // ---------------------------

    //  dadisp.GetData("version")

    // ---------------------------

 

    // Convert the wide-character string to a BSTR.

    CstrToBstr("version", &bstrIn);

 

    // Allocate a variant for the returned parameter.

    ::VariantInit(&varResult);

 

    // Invoke the function.

    hr = pIDadisp->GetData(bstrIn, &varResult);

 

    // Display the returned value

    DisplayVariant(&varResult);

 

    // ------------------------------------

    //  dadisp.GetData("max(gnorm(100,1))")

    // ------------------------------------

 

    ::SysFreeString(bstrIn);

    CstrToBstr("max(gnorm(100,1))", &bstrIn);

 

    // Allocate a variant for the returned parameter.

    ::VariantInit(&varResult);

 

    // Invoke the function.

    hr = pIDadisp->GetData(bstrIn, &varResult);

 

    // Display the returned value

    DisplayVariant(&varResult);

 

    // ---------------------------------------

    //  dadisp.PutSeries("MyVar", LinearArray)

    // ---------------------------------------

 

    ::SysFreeString(bstrIn);

    CstrToBstr("MyVar", &bstrIn);

 

    // create a Linear array

    CreateLinearArray(darray, ARRAY_SIZE*ARRAY_SIZE);

 

    // convert to automation SafeArray

    psa = DarrayToSafeArray(darray, ARRAY_SIZE, ARRAY_SIZE);

 

    // Invoke the function.

    hr = pIDadisp->PutSeries(bstrIn, psa, &iResult);

 

    // Display the input array

    DisplayArray(psa, VT_R8);

 

    // --------------------------------------

    //  dadisp.GetComplexSeries("fft(MyVar)")

    // --------------------------------------

 

    ::SysFreeString(bstrIn);

    CstrToBstr("fft(MyVar)", &bstrIn);

 

    // create two empty SafeArrays

    psaRe = CreateSafeArray();

    psaIm = CreateSafeArray();

 

    // Invoke the function.

    hr = pIDadisp->GetComplexSeries(bstrIn, &psaRe, &psaIm, 1, &iResult);

 

    // Display the returned arrays

    DisplayArray(psaRe, VT_R8);

    DisplayArray(psaIm, VT_R8);

 

    // Release the interface.

    if (pIDadisp) pIDadisp->Release();

    

    // Uninitialize the OLE library.

    OleUninitialize();

    

    return(status);

}

 

 

Obviously, the C++ programmer has more work to do, but benefits from much faster execution.

 

Automation passes strings in BSTR (BASIC String) format and the CstrtoBstr routine makes the necessary conversion. CreateSafeArray creates an empty SafeArray.

 

The routines CstrtoBstr, CreateSafeArray and other C++ ActiveX source files are available in the spl\activex release directory.