Передача массива через OLE

Программирование на Атлантисе (VIP, FCOM, ARD), FastReport

Модераторы: m0p3e, edward_K, Модераторы

Ответить
Kremanto13
Сообщения: 2
Зарегистрирован: 04 авг 2023, 10:33

Передача массива через OLE

Сообщение Kremanto13 »

Всем добрый день!
Возникла проблема. В нашей организации есть метод расчета массы нефти (методы ПОкМИ), который вызывается через OLE. Данный метод принимает в себя как простые типы данных, так и данные типа массив либо double, либо integer. Во время выполнения интерфейса, который вызывает работу этого метода, галактика вылетает с ошибкой:
"Runtime error 216 (rtl: попытка обращения к некоректному дескриптору) in streams_.dll at 0002AC53".

В логах находится следующая информация:

Необработанная исключительная ситуация
Код исключения: C0000005 (Общее нарушение защиты доступа к памяти)
Параметры исключения (2): 00000000 00000008
Адрес исключения: 013CAC53 streams_.dll.1:00029C53\

В отладчике удалось отследить, что передача в OLE простых данных идет без вылета, а проблема возникает, как только происходит попытка передать через OLE массив.
Часть кода вызова представлена ниже

Код: Выделить всё

type
  doubleArr  = array [1..1] of double;
  intArr     = array [1..1] of integer;
 
  Function CalcMI44(wPlotn :double; wMEmpty :double; wMLoaded :double; wName :string): double;
{
  var MI44_TankCount           : integer = 0;     // Число цистерн в составе  INT 0 >= 1
  var MI44_ScaleLimit_empty    : double = 0;      // Наибольший предел взвешивания средства измерений массы порожней цистерны кг DOUBLE 0.0 >= 1
  var MI44_ScaleLimit_loaded   : double = 0;      // Наибольший предел взвешивания средства измерений массы груженой цистерны кг DOUBLE 0.0 >= 1
  var MI44_M_empty             : doubleArr;      // Масса порожней цистерны кг DOUBLE NULL >= 1
  var MI44_M_loaded            : doubleArr;      // Масса груженой цистерны кг DOUBLE NULL >= M_empty[i] + 1
  var MI44_R                   : doubleArr;      // Плотность нефтепродукта в цистерне кг/м? DOUBLE NULL 470.4..1209.5
  var MI44_Tr                  : doubleArr;      // Температура нефтепродукта при измерении плотности °С DOUBLE NULL -40..150
  var MI44_Tcy                 : doubleArr;      // Температура, к которой приводится плотность и объем (15°С, 20°С) °С DOUBLE NULL 15; 20
  var MI44_Pr                  : doubleArr;      // Избыточное давление нефтепродукта в рабочих условиях МПа DOUBLE NULL 0..10.34214
  var MI44_ToolType            : intArr;           // Тип средства измерения плотности  ToolTypeEnum NULL
  var MI44_DeltaAbs_R          : doubleArr;      // Абсолютная погрешность измерений плотности кг/м? DOUBLE NULL 0..1.5|0.5|0.5
  var MI44_DeltaOtn_R          : doubleArr;      // Относительная погрешность измерений плотности % DOUBLE NULL 0..100

  var MI44_DeltaAbs_M_empty    : doubleArr;  // Абсолютная погрешность измерений массы порожней цистерны кг DOUBLE NULL
  var MI44_DeltaAbs_M_loaded   : doubleArr;  // Абсолютная погрешность измерений массы груженой цистерны кг DOUBLE NULL
  var MI44_M                   : doubleArr;  // Масса нефтепродукта в цистерне кг DOUBLE NULL
  var MI44_DeltaOtn_M          : doubleArr;  // Относительная погрешность измерений массы нефтепродукта в цистерне % DOUBLE NULL <= 2.5
  var MI44_Rcy                 : doubleArr;  // Плотность нефтепродукта в цистерне, приведенная к стандартным условиям кг/м? DOUBLE NULL
  var MI44_Vcy                 : doubleArr;  // Объем нефтепродукта в цистерне, приведенный к стандартным условиям м? DOUBLE NULL
  var MI44_DeltaOtn_Vcy        : doubleArr;  // Относительная погрешность измерений объема нефтепродукта в цистерне, приведенного к стандартным условиям % DOUBLE NULL
  var MI44_CTL_obs_base        : doubleArr;  // Поправочный коэффициент, учитывающий влияние температуры на плотность нефтепродукта, CTL  DOUBLE NULL
  var MI44_CPL_obs_base        : doubleArr;  // Поправочный коэффициент, учитывающий влияние давления на плотность нефтепродукта, CPL  DOUBLE NULL
  var MI44_CTPL_obs_base       : doubleArr;  // Поправочный коэффициент, учитывающий влияние температуры и давления на плотность нефтепродукта, CTPL  DOUBLE NULL
  var MI44_Fp_obs_base         : doubleArr;  // Коэффициент сжимаемости нефтепродукта, учитывающий влияние на плотность нефтепродукта, Fp 1/Па DOUBLE NULL
  var MI44_VolumetricExpansion : doubleArr;  // Коэффициент объемного расширения нефтепродукта 1/°С DOUBLE NULL
  var MI44_M_empty_total       : double = 0;  // Масса порожнего состава (партии) кг DOUBLE 0.0
  var MI44_M_loaded_total      : double = 0;  // Масса груженого состава (партии) кг DOUBLE 0.0
  var MI44_M_total             : double = 0;  // Масса нефтепродукта в составе (партии) кг DOUBLE 0.0
  var MI44_Vcy_total           : double = 0;  // Объем нефтепродукта в составе (партии), приведенный к стандартным условиям м? DOUBLE 0.0
  var MI44_DeltaOtn_M_total    : double = 0;  // Относительная погрешность измерений массы нефтепродукта в составе (партии) % DOUBLE 0.0
  var MI44_DeltaOtn_Vcy_total  : double = 0;  // Относительная погрешность измерений объема нефтепродукта в составе (партии), приведенного к стандартным условиям % DOUBLE 0.0

  var MI44_DllVersion          : string = '';
  var MI44_Result              : longint = 0;
  var MI44_ResultDetail        : string = '';
  var MI44_Warnings            : string = '';
  var Res                      : variant;
  var wRez                     : double  = 0;
//  var wGrad                    : string  = '';
//  var sTmp                     : string  = '';

  Result := 0;

  if not IsValid(#TabNC) OR ( wCalcMassa <> 0 )    then Exit; 

  SetLimit(MI44_M_empty,1);
  SetLimit(MI44_M_loaded,1);
  SetLimit(MI44_R,1);
  SetLimit(MI44_Tr,1);
  SetLimit(MI44_Tcy,1);
  SetLimit(MI44_Pr,1);
  SetLimit(MI44_ToolType,1);
  SetLimit(MI44_DeltaAbs_R,1);
  SetLimit(MI44_DeltaOtn_R,1);
  SetLimit(MI44_DeltaAbs_M_empty,1);
  SetLimit(MI44_DeltaAbs_M_loaded,1);
  SetLimit(MI44_M,1);
  SetLimit(MI44_DeltaOtn_M,1);
  SetLimit(MI44_Rcy,1);
  SetLimit(MI44_Vcy,1);
  SetLimit(MI44_DeltaOtn_Vcy,1);
  SetLimit(MI44_CTL_obs_base,1);
  SetLimit(MI44_CPL_obs_base,1);
  SetLimit(MI44_CTPL_obs_base,1);
  SetLimit(MI44_Fp_obs_base,1);
  SetLimit(MI44_VolumetricExpansion,1);

  //Входные данные
  MI44_TankCount              := 1;                  // Число цистерн в составе  INT 0 >= 1                                                              //1 - константа
  MI44_ScaleLimit_empty       := 1;                  // Наибольший предел взвешивания средства измерений массы порожней цистерны кг DOUBLE 0.0 >= 1
  MI44_ScaleLimit_loaded      := 1;                  // Наибольший предел взвешивания средства измерений массы груженой цистерны кг DOUBLE 0.0 >= 1
  MI44_M_empty[1]             := wMEmpty;            // Масса порожней цистерны кг DOUBLE NULL >= 1
  MI44_M_loaded[1]            := wMLoaded;           // Масса груженой цистерны кг DOUBLE NULL >= M_empty[i] + 1
  MI44_R[1]                   := wPlotn * 1000;      // Плотность нефтепродукта в цистерне кг/м? DOUBLE NULL 470.4..1209.5
  MI44_Tr[1]                  := 20;                 // Температура нефтепродукта при измерении плотности °С DOUBLE NULL -40..150
  MI44_Tcy[1]                 := 20;                 // Температура, к которой приводится плотность и объем (15°С, 20°С) °С DOUBLE NULL 15; 20
  MI44_Pr[1]                  := 0;                  // Избыточное давление нефтепродукта в рабочих условиях МПа DOUBLE NULL 0..10.34214
  MI44_ToolType[1]            := 2;                  // Тип средства измерения плотности  ToolTypeEnum NULL                                              // 2 - Ареометр, откалиброванный при 20°С
  MI44_DeltaAbs_R[1]          := 0.5;                // Абсолютная погрешность измерений плотности кг/м? DOUBLE NULL 0..1.5|0.5|0.5
  MI44_DeltaOtn_R[1]          := 0;                  // Относительная погрешность измерений плотности % DOUBLE NULL 0..100

  MI44_DeltaAbs_M_empty[1]    := 0;
  MI44_DeltaAbs_M_loaded[1]   := 0;
  MI44_M[1]                   := 0;
  MI44_DeltaOtn_M[1]          := 0;
  MI44_Rcy[1]                 := 0;
  MI44_Vcy[1]                 := 0;
  MI44_DeltaOtn_Vcy[1]        := 0;
  MI44_CTL_obs_base[1]        := 0;
  MI44_CPL_obs_base[1]        := 0;
  MI44_CTPL_obs_base[1]       := 0;
  MI44_Fp_obs_base[1]         := 0;
  MI44_VolumetricExpansion[1] := 0;

  case wName of               // запросили входные параметры
  'TankCount'          : wRez  := MI44_TankCount            ;
  'ScaleLimit_empty'   : wRez  := MI44_ScaleLimit_empty     ;
  'ScaleLimit_loaded'  : wRez  := MI44_ScaleLimit_loaded    ;
  'M_empty'            : wRez  := MI44_M_empty[1]           ;
  'M_loaded'           : wRez  := MI44_M_loaded[1]          ;
  'R'                  : wRez  := MI44_R[1]                 ;
  'Tr'                 : wRez  := MI44_Tr[1]                ;
  'Tcy'                : wRez  := MI44_Tcy[1]               ;
  'Pr'                 : wRez  := MI44_Pr[1]                ;
  'ToolType'           : wRez  := MI44_ToolType[1]          ;
  'DeltaAbs_R'         : wRez  := MI44_DeltaAbs_R[1]        ;
  'DeltaOtn_R'         : wRez  := MI44_DeltaOtn_R[1]        ;
  else
  { // выполнить расчет
    if MI_Method44( // параметры
                    MI44_TankCount              ,  // Число цистерн в составе  INT 0 >= 1
                    MI44_ScaleLimit_empty       ,  // Наибольший предел взвешивания средства измерений массы порожней цистерны кг DOUBLE 0.0 >= 1
                    MI44_ScaleLimit_loaded      ,  // Наибольший предел взвешивания средства измерений массы груженой цистерны кг DOUBLE 0.0 >= 1
                    MI44_M_empty             ,  // Масса порожней цистерны кг DOUBLE NULL >= 1
                    MI44_M_loaded            ,  // Масса груженой цистерны кг DOUBLE NULL >= M_empty[i] + 1
                    MI44_R                   ,  // Плотность нефтепродукта в цистерне кг/м? DOUBLE NULL 470.4..1209.5
                    MI44_Tr                  ,  // Температура нефтепродукта при измерении плотности °С DOUBLE NULL -40..150
                    MI44_Tcy                 ,  // Температура, к которой приводится плотность и объем (15°С, 20°С) °С DOUBLE NULL 15; 20
                    MI44_Pr                  ,  // Избыточное давление нефтепродукта в рабочих условиях МПа DOUBLE NULL 0..10.34214
                    MI44_ToolType            ,  // Тип средства измерения плотности  ToolTypeEnum NULL
                    MI44_DeltaAbs_R          ,  // Абсолютная погрешность измерений плотности кг/м? DOUBLE NULL 0..1.5|0.5|0.5
                    MI44_DeltaOtn_R          ,  // Относительная погрешность измерений плотности % DOUBLE NULL 0..100
                    // Выходные значения
                    MI44_DeltaAbs_M_empty    ,  // Абсолютная погрешность измерений массы порожней цистерны кг DOUBLE NULL
                    MI44_DeltaAbs_M_loaded   ,  // Абсолютная погрешность измерений массы груженой цистерны кг DOUBLE NULL
                    MI44_M                   ,  // Масса нефтепродукта в цистерне кг DOUBLE NULL
                    MI44_DeltaOtn_M          ,  // Относительная погрешность измерений массы нефтепродукта в цистерне % DOUBLE NULL <= 2.5
                    MI44_Rcy                 ,  // Плотность нефтепродукта в цистерне, приведенная к стандартным условиям кг/м? DOUBLE NULL
                    MI44_Vcy                 ,  // Объем нефтепродукта в цистерне, приведенный к стандартным условиям м? DOUBLE NULL
                    MI44_DeltaOtn_Vcy        ,  // Относительная погрешность измерений объема нефтепродукта в цистерне, приведенного к стандартным условиям % DOUBLE NULL
                    MI44_CTL_obs_base        ,  // Поправочный коэффициент, учитывающий влияние температуры на плотность нефтепродукта, CTL  DOUBLE NULL
                    MI44_CPL_obs_base        ,  // Поправочный коэффициент, учитывающий влияние давления на плотность нефтепродукта, CPL  DOUBLE NULL
                    MI44_CTPL_obs_base       ,  // Поправочный коэффициент, учитывающий влияние температуры и давления на плотность нефтепродукта, CTPL  DOUBLE NULL
                    MI44_Fp_obs_base         ,  // Коэффициент сжимаемости нефтепродукта, учитывающий влияние на плотность нефтепродукта, Fp 1/Па DOUBLE NULL
                    MI44_VolumetricExpansion ,  // Коэффициент объемного расширения нефтепродукта 1/°С DOUBLE NULL
                    MI44_M_empty_total          ,  // Масса порожнего состава (партии) кг DOUBLE 0.0
                    MI44_M_loaded_total         ,  // Масса груженого состава (партии) кг DOUBLE 0.0
                    MI44_M_total                ,  // Масса нефтепродукта в составе (партии) кг DOUBLE 0.0
                    MI44_Vcy_total              ,  // Объем нефтепродукта в составе (партии), приведенный к стандартным условиям м? DOUBLE 0.0
                    MI44_DeltaOtn_M_total       ,  // Относительная погрешность измерений массы нефтепродукта в составе (партии) % DOUBLE 0.0
                    MI44_DeltaOtn_Vcy_total     ,  // Относительная погрешность измерений объема нефтепродукта в составе (партии), приведенного к стандартным условиям % DOUBLE 0.0
                    MI44_DllVersion             ,
                    MI44_Result                 ,
                    MI44_ResultDetail           ,
                    MI44_Warnings               ,
                    Res                           ) then
    { // расчет без ошибок
      case wName of
        'DeltaAbs_M_empty'    : wRez := MI44_DeltaAbs_M_empty[1]    ;
        'DeltaAbs_M_loaded'   : wRez := MI44_DeltaAbs_M_loaded[1]   ;
        'M'                   : wRez := MI44_M[1]                   ;
        'DeltaOtn_M'          : wRez := MI44_DeltaOtn_M[1]          ;
        'Rcy'                 : wRez := MI44_Rcy[1]                 ;
        'Vcy '                : wRez := MI44_Vcy[1]                 ;
        'DeltaOtn_Vcy'        : wRez := MI44_DeltaOtn_Vcy[1]        ;
        'CTL_obs_base'        : wRez := MI44_CTL_obs_base[1]        ;
        'CPL_obs_base'        : wRez := MI44_CPL_obs_base[1]        ;
        'CTPL_obs_base'       : wRez := MI44_CTPL_obs_base[1]       ;
        'Fp_obs_base'         : wRez := MI44_Fp_obs_base[1]         ;
        'VolumetricExpansion' : wRez := MI44_VolumetricExpansion[1] ;
        'M_empty_total'       : wRez := MI44_M_empty_total       ;
        'M_loaded_total'      : wRez := MI44_M_loaded_total      ;
        'M_total'             : wRez := MI44_M_total             ;
        'Vcy_total'           : wRez := MI44_Vcy_total           ;
        'DeltaOtn_M_total'    : wRez := MI44_DeltaOtn_M_total    ;
        'DeltaOtn_Vcy_total'  : wRez := MI44_DeltaOtn_Vcy_total  ;
      end;
    }
  }
  end;

  Result := wRez;
}
  
В данном коде идет непосредственное обращение к ПОкМИ через OLE. Место, где происходит вылет - попытка передачи параметра "Масса порожней цистерны"

Код: Выделить всё

function MI_Method44(
      _MI44_TankCount           : integer;     // Число цистерн в составе  INT 0 >= 1
      //ScaleClass_empty    // Класс точности средства измерений массы порожней цистерны  ScalePrecisionEnum ScalePrecision_Unknown
      //ScaleClass_loaded   // Класс точности средства измерений массы груженой цистерны  ScalePrecisionEnum ScalePrecision_Unknown
      _MI44_ScaleLimit_empty    : double;      // Наибольший предел взвешивания средства измерений массы порожней цистерны кг DOUBLE 0.0 >= 1
      _MI44_ScaleLimit_loaded   : double;      // Наибольший предел взвешивания средства измерений массы груженой цистерны кг DOUBLE 0.0 >= 1
      _MI44_M_empty             : doubleArr;      // Масса порожней цистерны кг doubleArr NULL >= 1
      _MI44_M_loaded            : doubleArr;      // Масса груженой цистерны кг DOUBLE NULL >= M_empty[i] + 1
      _MI44_R                   : doubleArr;      // Плотность нефтепродукта в цистерне кг/м? DOUBLE NULL 470.4..1209.5
      _MI44_Tr                  : doubleArr;      // Температура нефтепродукта при измерении плотности °С DOUBLE NULL -40..150
      _MI44_Tcy                 : doubleArr;      // Температура, к которой приводится плотность и объем (15°С, 20°С) °С DOUBLE NULL 15; 20
      _MI44_Pr                  : doubleArr;      // Избыточное давление нефтепродукта в рабочих условиях МПа DOUBLE NULL 0..10.34214
      _MI44_ToolType            : intArr;     // Тип средства измерения плотности  ToolTypeEnum NULL
      //ToolAutomationLevel_R  Степень автоматизации средства измерения плотности  AutomationLevelEnum NULL
      _MI44_DeltaAbs_R          : doubleArr;      // Абсолютная погрешность измерений плотности кг/м? DOUBLE NULL 0..1.5|0.5|0.5
      _MI44_DeltaOtn_R          : doubleArr;      // Относительная погрешность измерений плотности % DOUBLE NULL 0..100

  var _MI44_DeltaAbs_M_empty    : doubleArr;  // Абсолютная погрешность измерений массы порожней цистерны кг DOUBLE NULL
  var _MI44_DeltaAbs_M_loaded   : doubleArr;  // Абсолютная погрешность измерений массы груженой цистерны кг DOUBLE NULL
  var _MI44_M                   : doubleArr;  // Масса нефтепродукта в цистерне кг DOUBLE NULL
  var _MI44_DeltaOtn_M          : doubleArr;  // Относительная погрешность измерений массы нефтепродукта в цистерне % DOUBLE NULL <= 2.5
  var _MI44_Rcy                 : doubleArr;  // Плотность нефтепродукта в цистерне, приведенная к стандартным условиям кг/м? DOUBLE NULL
  var _MI44_Vcy                 : doubleArr;  // Объем нефтепродукта в цистерне, приведенный к стандартным условиям м? DOUBLE NULL
  var _MI44_DeltaOtn_Vcy        : doubleArr;  // Относительная погрешность измерений объема нефтепродукта в цистерне, приведенного к стандартным условиям % DOUBLE NULL
  var _MI44_CTL_obs_base        : doubleArr;  // Поправочный коэффициент, учитывающий влияние температуры на плотность нефтепродукта, CTL  DOUBLE NULL
  var _MI44_CPL_obs_base        : doubleArr;  // Поправочный коэффициент, учитывающий влияние давления на плотность нефтепродукта, CPL  DOUBLE NULL
  var _MI44_CTPL_obs_base       : doubleArr;  // Поправочный коэффициент, учитывающий влияние температуры и давления на плотность нефтепродукта, CTPL  DOUBLE NULL
  var _MI44_Fp_obs_base         : doubleArr;  // Коэффициент сжимаемости нефтепродукта, учитывающий влияние на плотность нефтепродукта, Fp 1/Па DOUBLE NULL
  var _MI44_VolumetricExpansion : doubleArr;  // Коэффициент объемного расширения нефтепродукта 1/°С DOUBLE NULL
  var _MI44_M_empty_total       : double;  // Масса порожнего состава (партии) кг DOUBLE 0.0
  var _MI44_M_loaded_total      : double;  // Масса груженого состава (партии) кг DOUBLE 0.0
  var _MI44_M_total             : double;  // Масса нефтепродукта в составе (партии) кг DOUBLE 0.0
  var _MI44_Vcy_total           : double;  // Объем нефтепродукта в составе (партии), приведенный к стандартным условиям м? DOUBLE 0.0
  var _MI44_DeltaOtn_M_total    : double;  // Относительная погрешность измерений массы нефтепродукта в составе (партии) % DOUBLE 0.0
  var _MI44_DeltaOtn_Vcy_total  : double;  // Относительная погрешность измерений объема нефтепродукта в составе (партии), приведенного к стандартным условиям % DOUBLE 0.0


  var _MI44_DllVersion          : string;
  var _MI44_Result              : longint;
  var _MI44_ResultDetail        : string;
  var _MI44_Warnings            : string;
  var _Res                      : variant
) : boolean;

var MM_Ptr: TPtr;
{ // Расчет массы и объема нефтепродуктов в железнодорожных цистернах
  // Косвенный метод статических измерений

  Result := false;
  MM_Ptr := 0;

  SetLimit(_MI44_M_empty,1);
  SetLimit(_MI44_M_loaded,1);
  SetLimit(_MI44_R,1);
  SetLimit(_MI44_Tr,1);
  SetLimit(_MI44_Tcy,1);
  SetLimit(_MI44_Pr,1);
  SetLimit(_MI44_ToolType,1);
  SetLimit(_MI44_DeltaAbs_R,1);
  SetLimit(_MI44_DeltaOtn_R,1);
  SetLimit(_MI44_DeltaAbs_M_empty,1);
  SetLimit(_MI44_DeltaAbs_M_loaded,1);
  SetLimit(_MI44_M,1);
  SetLimit(_MI44_DeltaOtn_M,1);
  SetLimit(_MI44_Rcy,1);
  SetLimit(_MI44_Vcy,1);
  SetLimit(_MI44_DeltaOtn_Vcy,1);
  SetLimit(_MI44_CTL_obs_base,1);
  SetLimit(_MI44_CPL_obs_base,1);
  SetLimit(_MI44_CTPL_obs_base,1);
  SetLimit(_MI44_Fp_obs_base,1);
  SetLimit(_MI44_VolumetricExpansion,1);

  _try
  {
    MM_Ptr := OleCreate('Rosneft.MethodOfMetering44');

    OleCall1(MM_Ptr, ocPut, 'TankCount'          , _MI44_TankCount           );       // Число цистерн в составе  INT 0 >= 1
    OleCall1(MM_Ptr, ocPut, 'ScaleLimit_empty'   , _MI44_ScaleLimit_empty    );       // Наибольший предел взвешивания средства измерений массы порожней цистерны кг DOUBLE 0.0 >= 1
    OleCall1(MM_Ptr, ocPut, 'ScaleLimit_loaded'  , _MI44_ScaleLimit_loaded   );       // Наибольший предел взвешивания средства измерений массы груженой цистерны кг DOUBLE 0.0 >= 1
    
    //Ниже находится оператор, в котором происходит ошибка
    OleCall1(MM_Ptr, ocPut, 'M_empty'            , _MI44_M_empty             );       // Масса порожней цистерны кг DOUBLE NULL >= 1
    OleCall1(MM_Ptr, ocPut, 'M_loaded'           , _MI44_M_loaded            );       // Масса груженой цистерны кг DOUBLE NULL >= M_empty[i] + 1
    OleCall1(MM_Ptr, ocPut, 'R'                  , _MI44_R                   );       // Плотность нефтепродукта в цистерне кг/м? DOUBLE NULL 470.4..1209.5
    OleCall1(MM_Ptr, ocPut, 'Tr'                 , _MI44_Tr                  );       // Температура нефтепродукта при измерении плотности °С DOUBLE NULL -40..150
    OleCall1(MM_Ptr, ocPut, 'Tcy'                , _MI44_Tcy                 );       // Температура, к которой приводится плотность и объем (15°С, 20°С) °С DOUBLE NULL 15; 20
    OleCall1(MM_Ptr, ocPut, 'Pr'                 , _MI44_Pr                  );       // Избыточное давление нефтепродукта в рабочих условиях МПа DOUBLE NULL 0..10.34214
    OleCall1(MM_Ptr, ocPut, 'ToolType'           , _MI44_ToolType            );       // Тип средства измерения плотности  ToolTypeEnum NULL
    OleCall1(MM_Ptr, ocPut, 'DeltaAbs_R'         , _MI44_DeltaAbs_R          );       // Абсолютная погрешность измерений плотности кг/м? DOUBLE NULL 0..1.5|0.5|0.5
    OleCall1(MM_Ptr, ocPut, 'DeltaOtn_R'         , _MI44_DeltaOtn_R          );       // Относительная погрешность измерений плотности % DOUBLE NULL 0..100


    OleCall1(MM_Ptr, ocFunc,'Exec'               , _Res                      );
    OleCall1(MM_Ptr, ocGet, 'Result'             , _MI44_Result              );
    OleCall1(MM_Ptr, ocGet, 'ResultDetail'       , _MI44_ResultDetail        );
    OleCall1(MM_Ptr, ocGet, 'Warnings'           , _MI44_Warnings            );
    OleCall1(MM_Ptr, ocGet, 'DllVersion'         , _MI44_DllVersion          );

    OleCall1(MM_Ptr, ocGet, 'DeltaAbs_M_empty'   , _MI44_DeltaAbs_M_empty    );       // Абсолютная погрешность измерений массы порожней цистерны кг DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'DeltaAbs_M_loaded'  , _MI44_DeltaAbs_M_loaded   );       // Абсолютная погрешность измерений массы груженой цистерны кг DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'M'                  , _MI44_M                   );       // Масса нефтепродукта в цистерне кг DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'DeltaOtn_M'         , _MI44_DeltaOtn_M          );       // Относительная погрешность измерений массы нефтепродукта в цистерне % DOUBLE NULL <= 2.5
    OleCall1(MM_Ptr, ocGet, 'Rcy'                , _MI44_Rcy                 );       // Плотность нефтепродукта в цистерне, приведенная к стандартным условиям кг/м? DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'Vcy'                , _MI44_Vcy                 );       // Объем нефтепродукта в цистерне, приведенный к стандартным условиям м? DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'DeltaOtn_Vcy'       , _MI44_DeltaOtn_Vcy        );       // Относительная погрешность измерений объема нефтепродукта в цистерне, приведенного к стандартным условиям % DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'CTL_obs_base'       , _MI44_CTL_obs_base        );       // Поправочный коэффициент, учитывающий влияние температуры на плотность нефтепродукта, CTL  DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'CPL_obs_base'       , _MI44_CPL_obs_base        );       // Поправочный коэффициент, учитывающий влияние давления на плотность нефтепродукта, CPL  DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'CTPL_obs_base'      , _MI44_CTPL_obs_base       );       // Поправочный коэффициент, учитывающий влияние температуры и давления на плотность нефтепродукта, CTPL  DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'Fp_obs_base'        , _MI44_Fp_obs_base         );       // Коэффициент сжимаемости нефтепродукта, учитывающий влияние на плотность нефтепродукта, Fp 1/Па DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'VolumetricExpansion', _MI44_VolumetricExpansion );       // Коэффициент объемного расширения нефтепродукта 1/°С DOUBLE NULL
    OleCall1(MM_Ptr, ocGet, 'M_empty_total'      , _MI44_M_empty_total       );       // Масса порожнего состава (партии) кг DOUBLE 0.0
    OleCall1(MM_Ptr, ocGet, 'M_loaded_total'     , _MI44_M_loaded_total      );       // Масса груженого состава (партии) кг DOUBLE 0.0
    OleCall1(MM_Ptr, ocGet, 'M_total'            , _MI44_M_total             );       // Масса нефтепродукта в составе (партии) кг DOUBLE 0.0
    OleCall1(MM_Ptr, ocGet, 'Vcy_total'          , _MI44_Vcy_total           );       // Объем нефтепродукта в составе (партии), приведенный к стандартным условиям м? DOUBLE 0.0
    OleCall1(MM_Ptr, ocGet, 'DeltaOtn_M_total'   , _MI44_DeltaOtn_M_total    );       // Относительная погрешность измерений массы нефтепродукта в составе (партии) % DOUBLE 0.0
    OleCall1(MM_Ptr, ocGet, 'DeltaOtn_Vcy_total' , _MI44_DeltaOtn_Vcy_total  );       // Относительная погрешность измерений объема нефтепродукта в составе (партии), приведенного к стандартным условиям % DOUBLE 0.0

    OleDestroy(MM_Ptr);

    if Trim(_MI44_DllVersion) = '1.0.4.0' then
      Result := true;
    else
      message('Проверьте версию библиотеки для расчета массы нефтепродуктов!', Error+OkButton);
  }
  _except
    on ExOleCantCreateObject:
    {
      _MI44_ResultDetail := 'OLE_ERROR!';
      message('Не найдена библиотека для расчета массы нефтепродуктов!', Error+OkButton);
    }
    else
    {
      _MI44_ResultDetail := ExploreException;
      message('Ошибка расчета. Проверьте версию библиотеки расчета масс!', Error+OkButton);
    }
}
Подозреваю, что я как-то не так передаю массив, но в чем конкретно - не понимаю. Прошу вас помочь
KVS
Посетитель
Сообщения: 36
Зарегистрирован: 03 фев 2020, 10:38

Re: Передача массива через OLE

Сообщение KVS »

Добрый день.

К сожалению, некоторые типы данных VIP'а представляют из себя немного не то, чем кажутся на самом деле (VIP'овый string - это ShortString в Delphi, например).
Реализация этих типов есть в разных dcu'шках, которые поставляются при приобретении лицензии разработчика на платформе Atlantis.

Мы решали подобные проблемы при помощи написания своей DLL на делфи, которая выступала в качестве прослойки для вызовов COM.
Идея такая:
1. Из VIP'па формируется файл с данными во временной директории, или заполняются массивы через множественный вызов методов а-ля ArrAdd, реализованных в своей DLL;
2. Уже на стороне DLL осуществляется вызов COM и передача результата в VIP.
Прямую передачу массивов нам победить не удалось.

Если нету Delphi, то можно писать на Lazarus.
oiko
Местный житель
Сообщения: 419
Зарегистрирован: 29 мар 2005, 17:49

Re: Передача массива через OLE

Сообщение oiko »

Проще наверное на випе написать этот метод расчета, если конечно в нем нет интегрального исчисления.
Как вариант вместо массива выгрузить в ексельный файл и передать его внешней программе как параметр.
Kremanto13
Сообщения: 2
Зарегистрирован: 04 авг 2023, 10:33

Re: Передача массива через OLE

Сообщение Kremanto13 »

oiko писал(а): 21 авг 2023, 11:35 Проще наверное на випе написать этот метод расчета, если конечно в нем нет интегрального исчисления.
К сожалению, нам дали эту библиотеку без "исходников", то есть то, каким конкретно образом работает расчет метода, нам неизвестно (да и никто не скажет), поэтому работаем таким образом.
KVS
Посетитель
Сообщения: 36
Зарегистрирован: 03 фев 2020, 10:38

Re: Передача массива через OLE

Сообщение KVS »

На всякий случай оставлю это здесь.
При передаче параметра из Галки в какую-либо экспортируемую функцию/процедуру из DLL нужно убедиться в том, что в сигнатуре функции типы указаны корректно.

Тип данных в переменных Галки можно посмотреть функцией VType, возвращаемое значение - константа типа данных.
Результат выполнения функции ищем в https://docwiki.embarcadero.com/RADStud ... alid_Types.

Например:

Код: Выделить всё

var s : string = '';
VType(s) = 8 //VT_BSTR = 8 = WideString. Т.е при передаче string в DLL, тип входящего параметра должен быть ShortString или WideString 

var d : date= date(1,1,2023);
VType(d) = 7 //VT_DATE = 7 = TDateTime. Т.е при передаче date в DLL, тип входящего параметра должен быть TDateTime

var s : wideString= '';
VType(s) = 8 //VT_BSTR = 8 = WideString. Однако ничего подобного, VIP'овский wideString не является типом WideString из делфи, а представляет из себя тип PWideStringData из streams_.dll

var l : longInt = 100500;
VType(l) = 3 //VT_I4 = 3 = Integer. Т.е при передаче longInt в DLL, тип входящего параметра должен быть Integer

И т.д.

Что касается структур VIP'a, то:
1. Массивы и структуры не приводятся к типу variant;
2. Не работает передача структур через OLE.

Энивей, рекомендую при написании своих DLL использовать простые типы данных - меньше шансов на разные ошибки при которых Галка тупо упадёт по рантайму.
Ответить