When the calling function uses a fixed array (eg Arrays: myData[2,24]), then I can access and copy all of the data in the array correctly, but since our array sizes are unknown at compile time, we really need to use dynamic arrays.
There appears to be some differences in implementation for MC64 handling of dynamic arrays vs the TS docs, so my question is: can you confirm the correct steps to access data in a dynamic array?
The following code snippet is based on the method outlined in the TS Extension guide for use with dynamic arrays, but it fails because it is expecting a handle to be returned from pELInputArray, but is just getting a data value.
Code: Select all
enDataType dt = pELInputArray->DataType; // dtDouble for fixed and dynamic!
if (dt == dtHandle)
{
// According to my understanding of the TS docs,
// pELInputArray->DataType should be a dtHandle type for dynamic arrays
// and this call should return the value of the handle:
int handle = pELInputArray->GetAsInteger(0); // should return dynamic array handle, but is 0
// since the handle is 0, this fails:
if (pELObj->System->Array->IsValidHandle(handle)) // <<== causes COM exception
{
IELFrameworkArrayPtr pDynArray = pELObj->System->Array;
for (int i = 0; i < input_sz; i++)
{
inputs[i] = pDynArray->GetFloatValue(handle, i);
}
}
}
When I change the array to a fixed size, I can access the array correctly using this snippet:
Code: Select all
for (int i = 0; i < input_sz; i++)
{
pELInputArray->SelectedIndex[0] = i;
inputs[i] = pELInputArray->GetAsDouble(0);
}
// This is the entire function
Code: Select all
extern "C" __declspec(dllexport) TestDynamicArrays(IEasyLanguageObject * pELObj, LPSTR Input_Array_Name)
{
// Find the EL variable for the passed array name
IEasyLanguageVariable* pELInputArray = pELObj->Variables[(char*)Input_Array_Name];
// Get the array shape
int input_dim = pELInputArray->Dimensions;
int input_sz = pELInputArray->DimensionSize[0];
double * inputs[input_sz];
// Copy data from the input array to our internal array
// This works if the array has fixed dimensions,
// but generates a COM error for dynamic arrays (SEE Below)
for (int i = 0; i < input_sz; i++)
{
pELInputArray->SelectedIndex[0] = i;
inputs[i] = pELInputArray->GetAsDouble(0);
}
// --------------------------------------------------------------------
// Dynamic Array handling
// This is how I understand data in dynamic arrays should be accessed
// based on the TS EL Extension Guide
// --------------------------------------------------------------------
// The variable DataType should be dtHandle for Dynamic arrays, but
// in MC64, it is the array data type (eg. dtDouble)
enDataType dt = pELInputArray->DataType; // dtDouble for fixed and dynamic!
if (dt == dtHandle)
{
int handle = pELInputArray->GetAsInteger(0); // should return dynamic array handle, but is 0
// handle should point to the dynamic array entry,
// but is 0, so this next statement will fail
if (pELObj->System->Array->IsValidHandle(handle)) // <<== causes COM exception
{
IELFrameworkArrayPtr pDynArray = pELObj->System->Array;
for (int i = 0; i < input_sz; i++)
{
pELInputArray->SelectedIndex[1] = i;
inputs[i] = pDynArray->GetFloatValue(handle, i);
}
}
}
}
This is the exception:
Exception thrown at 0x00007FFE23219689 in MultiCharts64.exe: Microsoft C++ exception: _com_error at memory location 0x00000000302CDCA8.
Exception thrown at 0x00007FFE23219689 in MultiCharts64.exe: Microsoft C++ exception: _com_error at memory location 0x00000000302CDD00.
Exception thrown at 0x00007FFE23219689 in MultiCharts64.exe: Microsoft C++ exception: _ELAPI_::_ELAPI_exception_Resolve at memory location 0x00000000302CE090.
Exception thrown at 0x00007FFE23219689 in MultiCharts64.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.
Exception thrown at 0x00007FFE23219689 in MultiCharts64.exe: Microsoft C++ exception: _ELAPI_::_ELAPI_exception_Resolve at memory location 0x00000000302CE090.
Exception thrown at 0x00007FFE23219689 in MultiCharts64.exe: Microsoft C++ exception: _ELAPI_::_WithSender_exception<IExceptionSender const ,_ELAPI_::_ELAPI_exception_Resolve> at memory location 0x00000000302CECF0.