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.