diff --git a/include/dss_capi.h b/include/dss_capi.h index bb6830a63..7cc4ae781 100644 --- a/include/dss_capi.h +++ b/include/dss_capi.h @@ -563,7 +563,9 @@ extern "C" { DSS_CAPI_DLL void Bus_Get_LoadList_GR(void); /*! - Array of 18 doubles (9 complex values) containing the complete 012 Zsc matrix + Array of doubles (complex) containing the complete 012 Zsc matrix. + Only available after Zsc is computed, either through the "ZscRefresh" command, or running a "FaultStudy" solution. + Only available for buses with 3 nodes. */ DSS_CAPI_DLL void Bus_Get_ZSC012Matrix(double** ResultPtr, int32_t* ResultCount); /*! @@ -1197,7 +1199,7 @@ extern "C" { DSS_CAPI_DLL void CktElement_Get_Powers_GR(void); /*! - Double array of symmetrical component currents into each 3-phase terminal + Double array of symmetrical component currents (magnitudes only) into each 3-phase terminal */ DSS_CAPI_DLL void CktElement_Get_SeqCurrents(double** ResultPtr, int32_t* ResultCount); /*! @@ -1206,7 +1208,7 @@ extern "C" { DSS_CAPI_DLL void CktElement_Get_SeqCurrents_GR(void); /*! - Double array of sequence powers into each 3-phase teminal + Complex array of sequence powers (kW, kvar) into each 3-phase teminal */ DSS_CAPI_DLL void CktElement_Get_SeqPowers(double** ResultPtr, int32_t* ResultCount); /*! @@ -1215,7 +1217,7 @@ extern "C" { DSS_CAPI_DLL void CktElement_Get_SeqPowers_GR(void); /*! - Double array of symmetrical component voltages at each 3-phase terminal + Double array of symmetrical component voltages (magnitudes only) at each 3-phase terminal */ DSS_CAPI_DLL void CktElement_Get_SeqVoltages(double** ResultPtr, int32_t* ResultCount); /*! @@ -1259,7 +1261,7 @@ extern "C" { DSS_CAPI_DLL int32_t CktElement_Get_NumProperties(void); /*! - Residual currents for each terminal: (mag, angle) + Residual currents for each terminal: (magnitude, angle in degrees) */ DSS_CAPI_DLL void CktElement_Get_Residuals(double** ResultPtr, int32_t* ResultCount); /*! @@ -1691,6 +1693,28 @@ extern "C" { */ DSS_CAPI_DLL uint16_t DSS_Get_AllowChangeDir(void); DSS_CAPI_DLL void DSS_Set_AllowChangeDir(uint16_t Value); + + /*! + If enabled, the engine will fill the array dimensions as the third and forth elements of + the "count" pointer (first elements is the current size, second is the capacity). For user-managed + memory, the user must provide a valid "count" pointer with the correct capacity. + + Most matrices from the DSS engine are column-major (a.k.a. "Fortran order"). + + If the array is not a matrix, the elements are left as zeroes, i.e. the current size can be used as + the dimension of the vector. + For complex matrices, the sizes are referred to the number of complex elements, not the primary the float64 elements. + + Defaults to False/0 in the 0.13.x versions of DSS C-API. + This might change to false in future versions. + + This can also be set through the environment variable DSS_CAPI_ARRAY_DIMS. Setting it to 1 to + enable the behavior on start-up. + + (API Extension) + */ + DSS_CAPI_DLL uint16_t DSS_Get_EnableArrayDimensions(void); + DSS_CAPI_DLL void DSS_Set_EnableArrayDimensions(uint16_t Value); /*! If enabled, in case of errors or empty arrays, the API returns arrays with values compatible with the @@ -2676,6 +2700,9 @@ extern "C" { */ DSS_CAPI_DLL double Lines_Get_X0(void); + /*! + Reactance matrix (full), ohms per unit length. Array of doubles. + */ DSS_CAPI_DLL void Lines_Get_Xmatrix(double** ResultPtr, int32_t* ResultCount); /*! Same as Lines_Get_Xmatrix but using the global buffer interface for results diff --git a/include/dss_capi_ctx.h b/include/dss_capi_ctx.h index 9f3137c91..1c49549fd 100644 --- a/include/dss_capi_ctx.h +++ b/include/dss_capi_ctx.h @@ -391,7 +391,9 @@ extern "C" { DSS_CAPI_DLL void ctx_Bus_Get_LoadList_GR(void* ctx); /*! - Array of 18 doubles (9 complex values) containing the complete 012 Zsc matrix + Array of doubles (complex) containing the complete 012 Zsc matrix. + Only available after Zsc is computed, either through the "ZscRefresh" command, or running a "FaultStudy" solution. + Only available for buses with 3 nodes. */ DSS_CAPI_DLL void ctx_Bus_Get_ZSC012Matrix(void* ctx, double** ResultPtr, int32_t* ResultCount); /*! @@ -1025,7 +1027,7 @@ extern "C" { DSS_CAPI_DLL void ctx_CktElement_Get_Powers_GR(void* ctx); /*! - Double array of symmetrical component currents into each 3-phase terminal + Double array of symmetrical component currents (magnitudes only) into each 3-phase terminal */ DSS_CAPI_DLL void ctx_CktElement_Get_SeqCurrents(void* ctx, double** ResultPtr, int32_t* ResultCount); /*! @@ -1034,7 +1036,7 @@ extern "C" { DSS_CAPI_DLL void ctx_CktElement_Get_SeqCurrents_GR(void* ctx); /*! - Double array of sequence powers into each 3-phase teminal + Complex array of sequence powers (kW, kvar) into each 3-phase teminal */ DSS_CAPI_DLL void ctx_CktElement_Get_SeqPowers(void* ctx, double** ResultPtr, int32_t* ResultCount); /*! @@ -1043,7 +1045,7 @@ extern "C" { DSS_CAPI_DLL void ctx_CktElement_Get_SeqPowers_GR(void* ctx); /*! - Double array of symmetrical component voltages at each 3-phase terminal + Double array of symmetrical component voltages (magnitudes only) at each 3-phase terminal */ DSS_CAPI_DLL void ctx_CktElement_Get_SeqVoltages(void* ctx, double** ResultPtr, int32_t* ResultCount); /*! @@ -1087,7 +1089,7 @@ extern "C" { DSS_CAPI_DLL int32_t ctx_CktElement_Get_NumProperties(void* ctx); /*! - Residual currents for each terminal: (mag, angle) + Residual currents for each terminal: (magnitude, angle in degrees) */ DSS_CAPI_DLL void ctx_CktElement_Get_Residuals(void* ctx, double** ResultPtr, int32_t* ResultCount); /*! @@ -1519,6 +1521,28 @@ extern "C" { */ DSS_CAPI_DLL uint16_t ctx_DSS_Get_AllowChangeDir(void* ctx); DSS_CAPI_DLL void ctx_DSS_Set_AllowChangeDir(void* ctx, uint16_t Value); + + /*! + If enabled, the engine will fill the array dimensions as the third and forth elements of + the "count" pointer (first elements is the current size, second is the capacity). For user-managed + memory, the user must provide a valid "count" pointer with the correct capacity. + + Most matrices from the DSS engine are column-major (a.k.a. "Fortran order"). + + If the array is not a matrix, the elements are left as zeroes, i.e. the current size can be used as + the dimension of the vector. + For complex matrices, the sizes are referred to the number of complex elements, not the primary the float64 elements. + + Defaults to False/0 in the 0.13.x versions of DSS C-API. + This might change to false in future versions. + + This can also be set through the environment variable DSS_CAPI_ARRAY_DIMS. Setting it to 1 to + enable the behavior on start-up. + + (API Extension) + */ + DSS_CAPI_DLL uint16_t ctx_DSS_Get_EnableArrayDimensions(void* ctx); + DSS_CAPI_DLL void ctx_DSS_Set_EnableArrayDimensions(void* ctx, uint16_t Value); /*! If enabled, in case of errors or empty arrays, the API returns arrays with values compatible with the @@ -2504,6 +2528,9 @@ extern "C" { */ DSS_CAPI_DLL double ctx_Lines_Get_X0(void* ctx); + /*! + Reactance matrix (full), ohms per unit length. Array of doubles. + */ DSS_CAPI_DLL void ctx_Lines_Get_Xmatrix(void* ctx, double** ResultPtr, int32_t* ResultCount); /*! Same as Lines_Get_Xmatrix but using the global buffer interface for results diff --git a/src/CAPI/CAPI_Bus.pas b/src/CAPI/CAPI_Bus.pas index 7024fe1b5..9215ba775 100644 --- a/src/CAPI/CAPI_Bus.pas +++ b/src/CAPI/CAPI_Bus.pas @@ -495,7 +495,7 @@ procedure Bus_Get_ZscMatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC if Assigned(Buses^[ActiveBusIndex].Zsc) then begin Nelements := Buses^[ActiveBusIndex].Zsc.Order; - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Nelements * Nelements); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Nelements * Nelements, Nelements, Nelements); iV := 0; with Buses^[ActiveBusIndex] do for i := 1 to Nelements do @@ -548,7 +548,7 @@ procedure Bus_Get_YscMatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC if Assigned(Buses^[ActiveBusIndex].Ysc) then begin Nelements := Buses^[ActiveBusIndex].Ysc.Order; - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Nelements * Nelements); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Nelements * Nelements, Nelements, Nelements); iV := 0; with Buses^[ActiveBusIndex] do for i := 1 to Nelements do @@ -1246,7 +1246,7 @@ procedure Bus_Get_ZSC012Matrix(var ResultPtr: PDouble; ResultCount: PAPISize); C Zsc012Temp.Free; // Return all the elements of ZSC012 - DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NValues); + DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NValues, NumNodesThisBus, NumNodesThisBus); Move(ZSC012.GetValuesArrayPtr(Norder)[1], ResultPtr[0], NValues * SizeOf(Double)); end; end; diff --git a/src/CAPI/CAPI_Circuit.pas b/src/CAPI/CAPI_Circuit.pas index c1493fcc0..926629539 100644 --- a/src/CAPI/CAPI_Circuit.pas +++ b/src/CAPI/CAPI_Circuit.pas @@ -652,7 +652,7 @@ procedure Circuit_Get_SystemY(var ResultPtr: PDouble; ResultCount: PAPISize); CD GetCompressedMatrix(hY, nBus + 1, nNZ, @ColPtr[0], @RowIdx[0], @cVals[0]); // allocate a square matrix - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NumNodes * NumNodes); // Make array for complex + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NumNodes * NumNodes, NumNodes, NumNodes); // Make array for complex // DSS_RecreateArray_PDouble already zero-fills the array diff --git a/src/CAPI/CAPI_CktElement.pas b/src/CAPI/CAPI_CktElement.pas index 9f7006fab..8b28fc403 100644 --- a/src/CAPI/CAPI_CktElement.pas +++ b/src/CAPI/CAPI_CktElement.pas @@ -361,7 +361,7 @@ procedure CktElement_Get_Currents(var ResultPtr: PDouble; ResultCount: PAPISize) with DSSPrime.ActiveCircuit.ActiveCktElement do begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * (NConds * NTerms)); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * (NConds * NTerms), NConds, NTerms); GetCurrents(pComplexArray(Result)); end end; @@ -388,7 +388,7 @@ procedure CktElement_Get_Voltages(var ResultPtr: PDouble; ResultCount: PAPISize) with DSSPrime.ActiveCircuit, ActiveCktElement do begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * (NConds * Nterms)); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * (NConds * Nterms), NConds, Nterms); // k := (Terminal-1)*numcond; // RCD 8-30-00 Changed iV := 0; for i := 1 to NConds * Nterms do @@ -553,7 +553,7 @@ procedure CktElement_Get_SeqCurrents(var ResultPtr: PDouble; ResultCount: PAPISi with DSSPrime.ActiveCircuit, ActiveCktElement do begin try - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 3 * NTerms); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 3 * NTerms, 3, NTerms); i012 := Allocmem(sizeof(Complex) * 3 * Nterms); // get complex seq voltages @@ -605,7 +605,7 @@ procedure CktElement_Get_SeqPowers(var ResultPtr: PDouble; ResultCount: PAPISize with DSSPrime.ActiveCircuit, ActiveCktElement do begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms); // allocate for kW and kvar + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms, 3, NTerms); // allocate for kW and kvar if NPhases <> 3 then begin if (Nphases = 1) and PositiveSequence then @@ -614,7 +614,7 @@ procedure CktElement_Get_SeqPowers(var ResultPtr: PDouble; ResultCount: PAPISize cBuffer := Allocmem(sizeof(Complex) * NValues); GetCurrents(cBuffer); iCount := 2; // Start with kW1 - {Put only phase 1 quantities in Pos seq} + // Put only phase 1 quantities in Pos seq for j := 1 to NTerms do begin k := (j - 1) * NConds; @@ -652,7 +652,7 @@ procedure CktElement_Get_SeqPowers(var ResultPtr: PDouble; ResultCount: PAPISize S := V012[i] * cong(I012[i]); Result[icount] := S.re * 0.003; // 3-phase kW conversion inc(icount); - Result[icount] := S.im * 0.003; // 3-phase kW conversion + Result[icount] := S.im * 0.003; // 3-phase kvar conversion inc(icount); end; end; @@ -670,7 +670,7 @@ procedure CktElement_Get_SeqPowers_GR(); CDECL; //------------------------------------------------------------------------------ procedure CktElement_Get_SeqVoltages(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL; -// All voltages of active ciruit element +// All voltages of active circuit element // magnitude only // returns a set of seq voltages (3) for each terminal // 0, 1, 2 sequence (0, +, -) @@ -692,7 +692,7 @@ procedure CktElement_Get_SeqVoltages(var ResultPtr: PDouble; ResultCount: PAPISi with DSSPrime.ActiveCircuit, ActiveCktElement do begin try - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, (3 * NTerms - 1) + 1); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 3 * NTerms, 3, NTerms); V012 := Allocmem(sizeof(Complex) * 3 * Nterms); // get complex seq voltages @@ -859,7 +859,7 @@ procedure CktElement_Get_Residuals(var ResultPtr: PDouble; ResultCount: PAPISize with DSSPrime.ActiveCircuit.ActiveCktElement do begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NTerms); // 2 values per terminal + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NTerms, 2, NTerms); // 2 values per terminal cBuffer := Allocmem(sizeof(Complex) * Yorder); GetCurrents(cBuffer); iV := 0; @@ -889,8 +889,6 @@ procedure CktElement_Get_Residuals_GR(); CDECL; //------------------------------------------------------------------------------ procedure CktElement_Get_Yprim(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL; -{ Return the YPrim matrix for this element } - var cValues: pComplexArray; begin @@ -902,8 +900,10 @@ procedure CktElement_Get_Yprim(var ResultPtr: PDouble; ResultCount: PAPISize); C with DSSPrime.ActiveCircuit.ActiveCktElement do begin cValues := GetYprimValues(ALL_YPRIM); // Get pointer to complex array of values - if cValues = NIL then Exit; - DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Yorder * Yorder); + if cValues = NIL then + Exit; + + DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Yorder * Yorder, Yorder, Yorder); Move(cValues^, ResultPtr^, ResultCount^ * SizeOf(Double)); end end; @@ -1045,7 +1045,6 @@ function CktElement_Get_HasSwitchControl(): TAPIBoolean; CDECL; end; //------------------------------------------------------------------------------ procedure CktElement_Get_CplxSeqVoltages(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL; -{returns Seq Voltages as array of complex values} var S: String; begin @@ -1061,7 +1060,7 @@ procedure CktElement_Get_CplxSeqVoltages(var ResultPtr: PDouble; ResultCount: PA with DSSPrime.ActiveCircuit, ActiveCktElement do begin try - DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms); + DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms, 3, NTerms); CalcSeqVoltages(ActiveCktElement, pComplexArray(ResultPtr)); except @@ -1086,7 +1085,6 @@ procedure CktElement_Get_CplxSeqVoltages_GR(); CDECL; //------------------------------------------------------------------------------ procedure CktElement_Get_CplxSeqCurrents(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL; -{returns Seq Voltages as array of complex values} var Result: PDoubleArray0; i012: pComplexArray; @@ -1101,7 +1099,7 @@ procedure CktElement_Get_CplxSeqCurrents(var ResultPtr: PDouble; ResultCount: PA with DSSPrime.ActiveCircuit, ActiveCktElement do begin try - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms, 3, NTerms); i012 := pComplexArray(Result); // get complex seq voltages _CalcSeqCurrents(ActiveCktElement, i012); @@ -1279,7 +1277,7 @@ procedure CktElement_Get_NodeOrder(var ResultPtr: PInteger; ResultCount: PAPISiz Exit; end; - Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, NTerms * Nconds); + Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, NTerms * Nconds, Nconds, NTerms); k := 0; for i := 1 to Nterms do begin @@ -1375,7 +1373,7 @@ procedure CktElement_Get_CurrentsMagAng(var ResultPtr: PDouble; ResultCount: PAP with DSSPrime.ActiveCircuit.ActiveCktElement do begin NValues := NConds * NTerms; - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NValues); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NValues, 2, NValues); cBuffer := PComplexArray(ResultPtr); GetCurrents(cBuffer); iV := 0; @@ -1414,7 +1412,7 @@ procedure CktElement_Get_VoltagesMagAng(var ResultPtr: PDouble; ResultCount: PAP with DSSPrime.ActiveCircuit, ActiveCktElement do begin numcond := NConds * Nterms; - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * numcond); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * numcond, 2, numcond); // k := (Terminal-1)*numcond; // RCD 8-30-00 Changed iV := 0; for i := 1 to numcond do diff --git a/src/CAPI/CAPI_DSS.pas b/src/CAPI/CAPI_DSS.pas index b7847429e..ee4bff1c9 100644 --- a/src/CAPI/CAPI_DSS.pas +++ b/src/CAPI/CAPI_DSS.pas @@ -42,6 +42,8 @@ procedure DSS_RegisterPlotCallback(cb: dss_callback_plot_t); CDECL; procedure DSS_RegisterMessageCallback(cb: dss_callback_message_t); CDECL; function DSS_Get_AllowDOScmd(): TAPIBoolean; CDECL; procedure DSS_Set_AllowDOScmd(Value: TAPIBoolean); CDECL; +function DSS_Get_EnableArrayDimensions(): TAPIBoolean; CDECL; +procedure DSS_Set_EnableArrayDimensions(Value: TAPIBoolean); CDECL; implementation @@ -232,6 +234,29 @@ procedure DSS_Set_AllowChangeDir(Value: TAPIBoolean); CDECL; end; end; //------------------------------------------------------------------------------ +function DSS_Get_EnableArrayDimensions(): TAPIBoolean; CDECL; +begin + Result := DSS_CAPI_ARRAY_DIMS; +end; +//------------------------------------------------------------------------------ +procedure DSS_Set_EnableArrayDimensions(Value: TAPIBoolean); CDECL; +begin + DSS_CAPI_ARRAY_DIMS := Value; + if not Value then + with DSSPrime do + begin + // Clean-up any previous values to avoid issues in the consumers + GR_Counts_PPAnsiChar[2] := 0; + GR_Counts_PPAnsiChar[3] := 0; + GR_Counts_PDouble[2] := 0; + GR_Counts_PDouble[3] := 0; + GR_Counts_PInteger[2] := 0; + GR_Counts_PInteger[3] := 0; + GR_Counts_PByte[2] := 0; + GR_Counts_PByte[3] := 0; + end; +end; +//------------------------------------------------------------------------------ procedure DSS_RegisterPlotCallback(cb: dss_callback_plot_t); CDECL; begin DSSPrime.DSSPlotCallback := cb; diff --git a/src/CAPI/CAPI_LineCodes.pas b/src/CAPI/CAPI_LineCodes.pas index 9a0801c54..c920ab9e4 100644 --- a/src/CAPI/CAPI_LineCodes.pas +++ b/src/CAPI/CAPI_LineCodes.pas @@ -329,7 +329,7 @@ procedure LineCodes_Get_Cmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); with pLineCode do begin Factor := (TwoPi * BaseFrequency * 1.0e-9); - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, FNphases * FNphases); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, FNphases * FNphases, FNphases, FNphases); k := 0; for i := 1 to FNPhases do for j := 1 to FNphases do @@ -362,7 +362,7 @@ procedure LineCodes_Get_Rmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); with pLineCode do begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, FNphases * FNphases); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, FNphases * FNphases, FNphases, FNphases); k := 0; for i := 1 to FNPhases do for j := 1 to FNphases do @@ -395,7 +395,7 @@ procedure LineCodes_Get_Xmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); with pLineCode do begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, FNphases * FNphases); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, FNphases * FNphases, FNphases, FNphases); k := 0; for i := 1 to FNPhases do for j := 1 to FNphases do diff --git a/src/CAPI/CAPI_LineGeometries.pas b/src/CAPI/CAPI_LineGeometries.pas index 500a8a67f..d7c49bd30 100644 --- a/src/CAPI/CAPI_LineGeometries.pas +++ b/src/CAPI/CAPI_LineGeometries.pas @@ -201,7 +201,7 @@ procedure LineGeometries_Get_Cmatrix(var ResultPtr: PDouble; ResultCount: PAPISi mat := pLineGeometry.YCmatrix[Frequency, Length, Units]; Factor := (TwoPi * Frequency * 1.0e-9); - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, mat.Order * mat.Order); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, mat.Order * mat.Order, mat.Order, mat.Order); k := 0; for i := 1 to mat.Order do for j := 1 to mat.Order do @@ -232,7 +232,7 @@ procedure LineGeometries_Get_Rmatrix(var ResultPtr: PDouble; ResultCount: PAPISi end; mat := pLineGeometry.Zmatrix[Frequency, Length, Units]; - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, mat.Order * mat.Order); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, mat.Order * mat.Order, mat.Order, mat.Order); k := 0; for i := 1 to mat.Order do for j := 1 to mat.Order do @@ -263,7 +263,7 @@ procedure LineGeometries_Get_Xmatrix(var ResultPtr: PDouble; ResultCount: PAPISi end; mat := pLineGeometry.Zmatrix[Frequency, Length, Units]; - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, mat.Order * mat.Order); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, mat.Order * mat.Order, mat.Order, mat.Order); k := 0; for i := 1 to mat.Order do for j := 1 to mat.Order do @@ -295,7 +295,7 @@ procedure LineGeometries_Get_Zmatrix(var ResultPtr: PDouble; ResultCount: PAPISi mat := pLineGeometry.Zmatrix[Frequency, Length, Units]; data := mat.GetValuesArrayPtr(order); - DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * order * order); + DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * order * order, order, order); Move(data[1], ResultPtr[0], ResultCount[0] * SizeOf(Double)); end; diff --git a/src/CAPI/CAPI_Lines.pas b/src/CAPI/CAPI_Lines.pas index 119ab9406..7ae72872b 100644 --- a/src/CAPI/CAPI_Lines.pas +++ b/src/CAPI/CAPI_Lines.pas @@ -378,7 +378,7 @@ procedure Lines_Get_Cmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC with elem do begin Factor := TwoPi * BaseFrequency * 1.0e-9 * UnitsConvert; // corrected 2.9.2018 RCD - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, Nphases * Nphases); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, Nphases * Nphases, Nphases, Nphases); k := 0; for i := 1 to NPhases do for j := 1 to Nphases do @@ -423,7 +423,7 @@ procedure Lines_Get_Rmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC end; with elem do begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, Nphases * Nphases); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, Nphases * Nphases, Nphases, Nphases); k := 0; for i := 1 to NPhases do for j := 1 to Nphases do @@ -468,7 +468,7 @@ procedure Lines_Get_Xmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC end; with elem do begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, Nphases * Nphases); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, Nphases * Nphases, Nphases, Nphases); k := 0; for i := 1 to NPhases do for j := 1 to Nphases do @@ -782,7 +782,7 @@ procedure Lines_Get_Yprim(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL; Exit; // Get outta here end; - DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Yorder * Yorder); + DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Yorder * Yorder, Yorder, Yorder); Move(cValues[1], ResultPtr[0], 2 * Yorder * Yorder * SizeOf(Double)); end end; diff --git a/src/CAPI/CAPI_Obj.pas b/src/CAPI/CAPI_Obj.pas index 7bbde950d..87a682481 100644 --- a/src/CAPI/CAPI_Obj.pas +++ b/src/CAPI/CAPI_Obj.pas @@ -827,7 +827,7 @@ procedure Batch_GetPropSeq(var ResultPtr: PInteger; ResultCount: PAPISize; batch end; cls := batch^.ParentClass; N := cls.NumProperties + 1; - DSS_RecreateArray_PInteger(ResultPtr, ResultCount, batchSize * N); + DSS_RecreateArray_PInteger(ResultPtr, ResultCount, batchSize * N, N, batchSize); presult := ResultPtr; for i := 1 to batchSize do begin diff --git a/src/CAPI/CAPI_PDElements.pas b/src/CAPI/CAPI_PDElements.pas index fa88f54ab..cf0cdad68 100644 --- a/src/CAPI/CAPI_PDElements.pas +++ b/src/CAPI/CAPI_PDElements.pas @@ -567,7 +567,7 @@ procedure _PDElements_Get_AllCurrents_x(DSS: TDSSContext; var ResultPtr: PDouble pElem := pList.Next; end; - DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NValuesTotal * 2); // weird shape + DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NValuesTotal * 2); CResultPtr := PPolar(ResultPtr); // Get the actual values @@ -587,6 +587,12 @@ procedure _PDElements_Get_AllCurrents_x(DSS: TDSSContext; var ResultPtr: PDouble begin cBuffer := pComplexArray(ResultPtr); CResultPtr := PPolar(ResultPtr); + if DSS_CAPI_ARRAY_DIMS then + begin + ResultCount[2] := 2; + ResultCount[3] := NValuesTotal; + end; + for i := 1 to NValuesTotal do begin CResultPtr^ := ctopolardeg(cBuffer^[i]); @@ -709,7 +715,7 @@ procedure _PDElements_Get_AllxSeqCurrents(DSS: TDSSContext; var ResultPtr: PDoub if magnitude then begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NTermsTotal * 3); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NTermsTotal * 3, 3, NTermsTotal); i012 := i012v; for i := 0 to NTermsTotal * 3 - 1 do begin @@ -719,7 +725,7 @@ procedure _PDElements_Get_AllxSeqCurrents(DSS: TDSSContext; var ResultPtr: PDoub end else begin - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NTermsTotal * 3 * 2); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NTermsTotal * 3 * 2, 3, NTermsTotal); Move(i012v^, ResultPtr[0], NTermsTotal * 3 * 2 * SizeOf(Double)); end; diff --git a/src/CAPI/CAPI_Parser.pas b/src/CAPI/CAPI_Parser.pas index 4719fd39f..d21854a57 100644 --- a/src/CAPI/CAPI_Parser.pas +++ b/src/CAPI/CAPI_Parser.pas @@ -34,6 +34,7 @@ implementation uses CAPI_Constants, + DSSGlobals, ParserDel, ArrayDef, DSSClass; @@ -141,9 +142,16 @@ procedure Parser_Get_Vector_GR(ExpectedSize: Integer); CDECL; //------------------------------------------------------------------------------ procedure Parser_Get_Matrix(var ResultPtr: PDouble; ResultCount: PAPISize; ExpectedOrder: Integer); CDECL; +var + ActualOrder: Integer; begin DSS_RecreateArray_PDouble(ResultPtr, ResultCount, ExpectedOrder * ExpectedOrder); - DSSPrime.ComParser.ParseAsMatrix(ResultCount^, ArrayDef.PDoubleArray(ResultPtr)); + ActualOrder := DSSPrime.ComParser.ParseAsMatrix(ResultCount^, ArrayDef.PDoubleArray(ResultPtr)); + if (ActualOrder > 0) and (DSS_CAPI_ARRAY_DIMS) then + begin + ResultCount[2] := ActualOrder; + ResultCount[3] := ActualOrder; + end; end; procedure Parser_Get_Matrix_GR(ExpectedOrder: Integer); CDECL; @@ -154,9 +162,16 @@ procedure Parser_Get_Matrix_GR(ExpectedOrder: Integer); CDECL; //------------------------------------------------------------------------------ procedure Parser_Get_SymMatrix(var ResultPtr: PDouble; ResultCount: PAPISize; ExpectedOrder: Integer); CDECL; +var + ActualOrder: Integer; begin DSS_RecreateArray_PDouble(ResultPtr, ResultCount, ExpectedOrder * ExpectedOrder); - DSSPrime.ComParser.ParseAsSymMatrix(ResultCount^, ArrayDef.PDoubleArray(ResultPtr)); + ActualOrder := DSSPrime.ComParser.ParseAsSymMatrix(ResultCount^, ArrayDef.PDoubleArray(ResultPtr)); + if (ActualOrder > 0) and (DSS_CAPI_ARRAY_DIMS) then + begin + ResultCount[2] := ActualOrder; + ResultCount[3] := ActualOrder; + end; end; procedure Parser_Get_SymMatrix_GR(ExpectedOrder: Integer); CDECL; diff --git a/src/CAPI/CAPI_Reactors.pas b/src/CAPI/CAPI_Reactors.pas index bbd194766..d83e825d3 100644 --- a/src/CAPI/CAPI_Reactors.pas +++ b/src/CAPI/CAPI_Reactors.pas @@ -531,7 +531,7 @@ procedure Reactors_Get_Rmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); C if pReactor.Rmatrix = NIL then Exit; //TODO: would an error here be useful? - DSS_RecreateArray_PDouble(ResultPtr, ResultCount, pReactor.Nphases * pReactor.Nphases); + DSS_RecreateArray_PDouble(ResultPtr, ResultCount, pReactor.Nphases * pReactor.Nphases, pReactor.Nphases, pReactor.Nphases); Move(pReactor.Rmatrix[1], ResultPtr^, ResultCount^ * SizeOf(Double)); end; @@ -553,7 +553,7 @@ procedure Reactors_Get_Xmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); C if pReactor.Xmatrix = NIL then Exit; - DSS_RecreateArray_PDouble(ResultPtr, ResultCount, pReactor.Nphases * pReactor.Nphases); + DSS_RecreateArray_PDouble(ResultPtr, ResultCount, pReactor.Nphases * pReactor.Nphases, pReactor.Nphases, pReactor.Nphases); Move(pReactor.Xmatrix[1], ResultPtr^, ResultCount^ * SizeOf(Double)); end; diff --git a/src/CAPI/CAPI_Transformers.pas b/src/CAPI/CAPI_Transformers.pas index 5a9f3d3af..965fbbb4f 100644 --- a/src/CAPI/CAPI_Transformers.pas +++ b/src/CAPI/CAPI_Transformers.pas @@ -626,7 +626,7 @@ procedure Transformers_Get_AllLossesByType(var ResultPtr: PDouble; ResultCount: end; lst := DSSPrime.ActiveCircuit.Transformers; - DSS_RecreateArray_PDouble(Result, ResultPtr, ResultCount, lst.Count * 2 * 3); + DSS_RecreateArray_PDouble(Result, ResultPtr, ResultCount, lst.Count * 2 * 3, 3, lst.Count); CResult := PComplexArray(ResultPtr); k := 1; elem := lst.First; @@ -640,7 +640,7 @@ procedure Transformers_Get_AllLossesByType(var ResultPtr: PDouble; ResultCount: elem := lst.Next; end; //TODO: shrink to remove extra elements? - + // Keep the results in VA (NOT kVA) for consistency with CktElement_Get_Losses end; diff --git a/src/CAPI/CAPI_Utils.pas b/src/CAPI/CAPI_Utils.pas index 5f45c80d9..8b6de5b7d 100644 --- a/src/CAPI/CAPI_Utils.pas +++ b/src/CAPI/CAPI_Utils.pas @@ -76,24 +76,23 @@ procedure DSS_Dispose_PPAnsiChar(var p: PPAnsiChar; cnt: TAPISize); CDECL; procedure DSS_Dispose_PPointer(var p: PPointer); CDECL; function DSS_CreateArray_PByte(var p: PByte; cnt: PAPISize; const incount: TAPISize): PByteArray; -function DSS_CreateArray_PSingle(var p: PSingle; cnt: PAPISize; const incount: TAPISize): PSingleArray0; -function DSS_CreateArray_PDouble(var p: PDouble; cnt: PAPISize; const incount: TAPISize): PDoubleArray0; -function DSS_CreateArray_PInteger(var p: PInteger; cnt: PAPISize; const incount: TAPISize): PIntegerArray0; +function DSS_CreateArray_PDouble(var p: PDouble; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PDoubleArray0; +function DSS_CreateArray_PInteger(var p: PInteger; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PIntegerArray0; function DSS_CreateArray_PPAnsiChar(var p: PPAnsiChar; cnt: PAPISize; const incount: TAPISize): PPAnsiCharArray0; function DSS_CreateArray_PPointer(var p: PPointer; cnt: PAPISize; const incount: TAPISize): PPointerArray0; // NOTE: these do not copy to copy old values procedure DSS_RecreateArray_PByte(var res: PByteArray; var p: PByte; cnt: PAPISize; const incount: TAPISize); -procedure DSS_RecreateArray_PSingle(var res: PSingleArray0; var p: PSingle; cnt: PAPISize; const incount: TAPISize); -procedure DSS_RecreateArray_PDouble(var res: PDoubleArray0; var p: PDouble; cnt: PAPISize; const incount: TAPISize); -procedure DSS_RecreateArray_PInteger(var res: PIntegerArray0; var p: PInteger; cnt: PAPISize; const incount: TAPISize); +procedure DSS_RecreateArray_PSingle(var res: PSingleArray0; var p: PSingle; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0); +procedure DSS_RecreateArray_PDouble(var res: PDoubleArray0; var p: PDouble; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0); +procedure DSS_RecreateArray_PInteger(var res: PIntegerArray0; var p: PInteger; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0); procedure DSS_RecreateArray_PPAnsiChar(var res: PPAnsiCharArray0; var p: PPAnsiChar; cnt: PAPISize; const incount: TAPISize); procedure DSS_RecreateArray_PPointer(var res: PPointerArray0; var p: PPointer; cnt: PAPISize; const incount: TAPISize); function DSS_RecreateArray_PByte(var p: PByte; cnt: PAPISize; const incount: TAPISize): PByteArray; -function DSS_RecreateArray_PSingle(var p: PSingle; cnt: PAPISize; const incount: TAPISize): PSingleArray0; -function DSS_RecreateArray_PDouble(var p: PDouble; cnt: PAPISize; const incount: TAPISize): PDoubleArray0; -function DSS_RecreateArray_PInteger(var p: PInteger; cnt: PAPISize; const incount: TAPISize): PIntegerArray0; +function DSS_RecreateArray_PSingle(var p: PSingle; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PSingleArray0; +function DSS_RecreateArray_PDouble(var p: PDouble; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PDoubleArray0; +function DSS_RecreateArray_PInteger(var p: PInteger; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PIntegerArray0; function DSS_RecreateArray_PPAnsiChar(var p: PPAnsiChar; cnt: PAPISize; const incount: TAPISize): PPAnsiCharArray0; function DSS_RecreateArray_PPointer(var p: PPointer; cnt: PAPISize; const incount: TAPISize): PPointerArray0; // MATLAB doesn't handle pointers that well, @@ -224,10 +223,10 @@ procedure DefaultResult(var ResultPtr: PSingle; ResultCount: PAPISize; Value: Si begin if not DSS_CAPI_COM_DEFAULTS then begin - DSS_RecreateArray_PSingle(ResultPtr, ResultCount, 0); + DSS_RecreateArray_PSingle(ResultPtr, ResultCount, 0, 0, 0); Exit; end; - DSS_RecreateArray_PSingle(ResultPtr, ResultCount, 1); + DSS_RecreateArray_PSingle(ResultPtr, ResultCount, 1, 0, 0); ResultPtr^ := Value; end; //------------------------------------------------------------------------------ @@ -360,28 +359,43 @@ function DSS_CreateArray_PByte(var p: PByte; cnt: PAPISize; const incount: TAPIS result := PByteArray(p); end; -function DSS_CreateArray_PSingle(var p: PSingle; cnt: PAPISize; const incount: TAPISize): PSingleArray0; +function DSS_CreateArray_PSingle(var p: PSingle; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PSingleArray0; begin cnt[0] := incount; cnt[1] := incount; p := AllocMem(incount * sizeof(Single)); result := PSingleArray0(p); + if (DSS_CAPI_ARRAY_DIMS) then + begin + cnt[2] := nr; + cnt[3] := nc; + end; end; -function DSS_CreateArray_PDouble(var p: PDouble; cnt: PAPISize; const incount: TAPISize): PDoubleArray0; +function DSS_CreateArray_PDouble(var p: PDouble; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PDoubleArray0; begin cnt[0] := incount; cnt[1] := incount; p := AllocMem(incount * sizeof(Double)); result := PDoubleArray0(p); + if (DSS_CAPI_ARRAY_DIMS) then + begin + cnt[2] := nr; + cnt[3] := nc; + end; end; -function DSS_CreateArray_PInteger(var p: PInteger; cnt: PAPISize; const incount: TAPISize): PIntegerArray0; +function DSS_CreateArray_PInteger(var p: PInteger; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PIntegerArray0; begin cnt[0] := incount; cnt[1] := incount; p := AllocMem(incount * sizeof(Integer)); result := PIntegerArray0(p); + if (DSS_CAPI_ARRAY_DIMS) then + begin + cnt[2] := nr; + cnt[3] := nc; + end; end; function DSS_CreateArray_PPAnsiChar(var p: PPAnsiChar; cnt: PAPISize; const incount: TAPISize): PPAnsiCharArray0; @@ -401,24 +415,27 @@ function DSS_CreateArray_PPointer(var p: PPointer; cnt: PAPISize; const incount: end; //------------------------------------------------------------------------------ -function DSS_RecreateArray_PInteger(var p: PInteger; cnt: PAPISize; const incount: TAPISize): PIntegerArray0; +function DSS_RecreateArray_PInteger(var p: PInteger; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PIntegerArray0; begin if (cnt[1] < incount) then begin DSS_Dispose_PInteger(p); - Result := DSS_CreateArray_PInteger(p, cnt, incount); - end - else + Result := DSS_CreateArray_PInteger(p, cnt, incount, nr, nc); + Exit; + end; + cnt[0] := incount; + Result := PIntegerArray0(p); + FillByte(Result^, incount * sizeof(Integer), 0); // needs to zero it for compatibility + if (DSS_CAPI_ARRAY_DIMS) then begin - cnt[0] := incount; - Result := PIntegerArray0(p); - FillByte(Result^, incount * sizeof(Integer), 0); // needs to zero it for compatibility + cnt[2] := nr; + cnt[3] := nc; end; end; -procedure DSS_RecreateArray_PInteger(var res: PIntegerArray0; var p: PInteger; cnt: PAPISize; const incount: TAPISize); +procedure DSS_RecreateArray_PInteger(var res: PIntegerArray0; var p: PInteger; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0); begin - res := DSS_RecreateArray_PInteger(p, cnt, incount); + res := DSS_RecreateArray_PInteger(p, cnt, incount, nr, nc); end; //------------------------------------------------------------------------------ @@ -441,13 +458,11 @@ function DSS_RecreateArray_PPointer(var p: PPointer; cnt: PAPISize; const incoun begin DSS_Dispose_PPointer(p); Result := DSS_CreateArray_PPointer(p, cnt, incount); - end - else - begin - cnt[0] := incount; - Result := PPointerArray0(p); - FillByte(Result^, incount * sizeof(Pointer), 0); // needs to zero it for compatibility + Exit; end; + cnt[0] := incount; + Result := PPointerArray0(p); + FillByte(Result^, incount * sizeof(Pointer), 0); // needs to zero it for compatibility end; procedure DSS_RecreateArray_PPointer(var res: PPointerArray0; var p: PPointer; cnt: PAPISize; const incount: TAPISize); @@ -456,45 +471,52 @@ procedure DSS_RecreateArray_PPointer(var res: PPointerArray0; var p: PPointer; c end; //------------------------------------------------------------------------------ -function DSS_RecreateArray_PSingle(var p: PSingle; cnt: PAPISize; const incount: TAPISize): PSingleArray0; +function DSS_RecreateArray_PSingle(var p: PSingle; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PSingleArray0; begin if (cnt[1] < incount) then begin DSS_Dispose_PSingle(p); - Result := DSS_CreateArray_PSingle(p, cnt, incount); - end - else + Result := DSS_CreateArray_PSingle(p, cnt, incount, nr, nc); + Exit; + end; + cnt[0] := incount; + Result := PSingleArray0(p); + FillByte(Result^, incount * sizeof(Single), 0); // needs to zero it for compatibility + if (DSS_CAPI_ARRAY_DIMS) then begin - cnt[0] := incount; - Result := PSingleArray0(p); - FillByte(Result^, incount * sizeof(Single), 0); // needs to zero it for compatibility + cnt[2] := nr; + cnt[3] := nc; end; end; -procedure DSS_RecreateArray_PSingle(var res: PSingleArray0; var p: PSingle; cnt: PAPISize; const incount: TAPISize); +procedure DSS_RecreateArray_PSingle(var res: PSingleArray0; var p: PSingle; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0); begin - res := DSS_RecreateArray_PSingle(p, cnt, incount); + res := DSS_RecreateArray_PSingle(p, cnt, incount, nr, nc); end; //------------------------------------------------------------------------------ -function DSS_RecreateArray_PDouble(var p: PDouble; cnt: PAPISize; const incount: TAPISize): PDoubleArray0; +function DSS_RecreateArray_PDouble(var p: PDouble; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0): PDoubleArray0; begin if (cnt[1] < incount) then begin DSS_Dispose_PDouble(p); - Result := DSS_CreateArray_PDouble(p, cnt, incount); - end - else + Result := DSS_CreateArray_PDouble(p, cnt, incount, nr, nc); + Exit; + end; + + cnt[0] := incount; + Result := PDoubleArray0(p); + FillByte(Result^, incount * sizeof(Double), 0); // needs to zero it for compatibility + if (DSS_CAPI_ARRAY_DIMS) then begin - cnt[0] := incount; - Result := PDoubleArray0(p); - FillByte(Result^, incount * sizeof(Double), 0); // needs to zero it for compatibility + cnt[2] := nr; + cnt[3] := nc; end; end; -procedure DSS_RecreateArray_PDouble(var res: PDoubleArray0; var p: PDouble; cnt: PAPISize; const incount: TAPISize); +procedure DSS_RecreateArray_PDouble(var res: PDoubleArray0; var p: PDouble; cnt: PAPISize; const incount: TAPISize; const nr: TAPISize=0; const nc: TAPISize=0); begin - res := DSS_RecreateArray_PDouble(p, cnt, incount); + res := DSS_RecreateArray_PDouble(p, cnt, incount, nr, nc); end; //------------------------------------------------------------------------------ @@ -504,13 +526,11 @@ function DSS_RecreateArray_PByte(var p: PByte; cnt: PAPISize; const incount: TAP begin DSS_Dispose_PByte(p); Result := DSS_CreateArray_PByte(p, cnt, incount); - end - else - begin - cnt[0] := incount; - Result := PByteArray(p); - FillByte(Result^, incount * sizeof(Byte), 0); // needs to zero it for compatibility + Exit; end; + cnt[0] := incount; + Result := PByteArray(p); + FillByte(Result^, incount * sizeof(Byte), 0); // needs to zero it for compatibility end; procedure DSS_RecreateArray_PByte(var res: PByteArray; var p: PByte; cnt: PAPISize; const incount: TAPISize); diff --git a/src/Common/DSSGlobals.pas b/src/Common/DSSGlobals.pas index 256a4d331..76a701bcc 100644 --- a/src/Common/DSSGlobals.pas +++ b/src/Common/DSSGlobals.pas @@ -150,7 +150,7 @@ interface DSS_CAPI_EXT_ERRORS: Boolean = True; DSS_CAPI_ALLOW_CHANGE_DIR: Boolean = True; DSS_CAPI_COM_DEFAULTS: Boolean = True; - DSS_CAPI_MATRIX_SIZE: Boolean = False; + DSS_CAPI_ARRAY_DIMS: Boolean = False; GlobalDefaultBaseFreq: Double = 60.0; CPU_Freq : int64; // Used to store the CPU performance counter frequency (not the actual CPU frequency) CPU_Cores : integer; @@ -805,6 +805,9 @@ initialization // For the 0.12.x branch, default is True, disable at initialization when DSS_CAPI_ALLOW_CHANGE_DIR = 0 DSS_CAPI_ALLOW_CHANGE_DIR := (SysUtils.GetEnvironmentVariable('DSS_CAPI_ALLOW_CHANGE_DIR') <> '0'); + // For the 0.13.x branch, default is False, enable at initialization when DSS_CAPI_ARRAY_DIMS = 1 + DSS_CAPI_ARRAY_DIMS := (SysUtils.GetEnvironmentVariable('DSS_CAPI_ARRAY_DIMS') = '1'); + try DSSPrime := TDSSContext.Create(nil, True); except diff --git a/src/General/DSSObjectHelper.pas b/src/General/DSSObjectHelper.pas index c215029f9..6a2cdbb65 100644 --- a/src/General/DSSObjectHelper.pas +++ b/src/General/DSSObjectHelper.pas @@ -1047,7 +1047,7 @@ function TDSSClassHelper.GetObjPropertyJSONValue(obj: Pointer; Index: Integer; j begin ValueCount[0] := 0; ValueCount[1] := 0; - if DSS_CAPI_MATRIX_SIZE then + if DSS_CAPI_ARRAY_DIMS then begin ValueCount[2] := 0; ValueCount[3] := 0; @@ -1265,7 +1265,7 @@ function TDSSClassHelper.GetObjPropertyJSONValue(obj: Pointer; Index: Integer; j begin ValueCount[0] := 0; ValueCount[1] := 0; - if DSS_CAPI_MATRIX_SIZE then + if DSS_CAPI_ARRAY_DIMS then begin ValueCount[2] := 0; ValueCount[3] := 0; @@ -1396,7 +1396,7 @@ function TDSSClassHelper.GetObjPropertyValue(obj: Pointer; Index: Integer; out P begin ValueCount[0] := 0; ValueCount[1] := 0; - if DSS_CAPI_MATRIX_SIZE then + if DSS_CAPI_ARRAY_DIMS then begin ValueCount[2] := 0; ValueCount[3] := 0; @@ -1612,7 +1612,7 @@ function TDSSClassHelper.GetObjPropertyValue(obj: Pointer; Index: Integer; out P begin ValueCount[0] := 0; ValueCount[1] := 0; - if DSS_CAPI_MATRIX_SIZE then + if DSS_CAPI_ARRAY_DIMS then begin ValueCount[2] := 0; ValueCount[3] := 0; @@ -3104,10 +3104,10 @@ function TDSSClassHelper.GetObjObject(Obj: Pointer; Index: Integer): TDSSObject; end; end; -procedure TDSSClassHelper.GetObjDoubles(Obj: Pointer; Index: Integer; var ResultPtr: PDouble; ResultCount: PAPISize); +procedure TDSSClassHelper.GetObjDoubles(Obj: Pointer; Index: Integer; var ResultPtr: PDouble; ResultCount: PAPISize); //TODO: check for missing array sizes, especially when ReadByFunction var c: PComplex; - i, j, count, step: Integer; + i, j, count, dim1, dim2, step: Integer; doublePtr, outPtr: PDouble; mat: TCMatrix; scale: Double; @@ -3146,10 +3146,13 @@ procedure TDSSClassHelper.GetObjDoubles(Obj: Pointer; Index: Integer; var Result count := PropertyOffset2[Index] end else if TPropertyFlag.SizeIsFunction in PropertyFlags[Index] then - count := TIntegerPropertyFunction(Pointer(PropertyOffset3[Index]))(obj) + count := TIntegerPropertyFunction(Pointer(PropertyOffset3[Index]))(obj) //TODO: check if we can use a simple flag for this else count := PInteger(PByte(obj) + PropertyOffset2[Index])^; + dim1 := 0; + dim2 := 0; + if TPropertyFlag.ReadByFunction in PropertyFlags[Index] then begin TDoublesPropertyFunction(Pointer(PropertyReadFunction[Index]))(obj, ResultPtr, ResultCount); @@ -3164,12 +3167,16 @@ procedure TDSSClassHelper.GetObjDoubles(Obj: Pointer; Index: Integer; var Result doublePtr := PPDouble(PByte(obj) + PropertyOffset[Index])^; if PropertyType[Index] = TPropertyType.DoubleSymMatrixProperty then + begin + dim1 := count; + dim2 := count; count := count * count; + end; if (count <= 0) or (doublePtr = NIL) then Exit; - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, count); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, count, dim1, dim2); if PropertyScale[Index] <> 1 then begin for i := 1 to count do @@ -3192,7 +3199,7 @@ procedure TDSSClassHelper.GetObjDoubles(Obj: Pointer; Index: Integer; var Result if mat = NIL then Exit; - Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, mat.Order * mat.Order); + Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, mat.Order * mat.Order, mat.Order, mat.Order); outPtr := @Result[0]; if TPropertyFlag.ImagPart in PropertyFlags[Index] then @@ -3487,7 +3494,7 @@ procedure TDSSClassHelper.GetObjStrings(Obj: Pointer; Index: Integer; var Result begin ObjResultCount[0] := 0; ObjResultCount[1] := 0; - if DSS_CAPI_MATRIX_SIZE then + if DSS_CAPI_ARRAY_DIMS then begin ObjResultCount[2] := 0; ObjResultCount[3] := 0; diff --git a/src/dss_capi.lpr b/src/dss_capi.lpr index 7b6291d20..e900a2fca 100644 --- a/src/dss_capi.lpr +++ b/src/dss_capi.lpr @@ -532,6 +532,8 @@ DSS_Set_LegacyModels, // API extension DSS_Get_AllowChangeDir, // API extension DSS_Set_AllowChangeDir, // API extension + DSS_Get_EnableArrayDimensions, // API extension + DSS_Set_EnableArrayDimensions, // API extension DSS_Get_COMErrorResults, // API extension DSS_Set_COMErrorResults, // API extension DSS_Get_AllowDOScmd, // API extension