Главная страница
Навигация по странице:

  • 12.5. Примеры работы с данными Автоматизации

  • 12.7. Как воспользоваться объектом ActiveX

  • 12.8. Применение конструктора модулей

  • современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран


    Скачать 2.24 Mb.
    НазваниеО. В. Бартеньев Современный Фортран
    Анкорсовременный фортран , Бортеньев.pdf
    Дата28.05.2018
    Размер2.24 Mb.
    Формат файлаpdf
    Имя файласовременный фортран , Бортеньев.pdf
    ТипДокументы
    #19729
    страница42 из 49
    1   ...   38   39   40   41   42   43   44   45   ...   49
    12.4. Идентификация объекта
    Идентификация объекта ActiveX выполняется по глобальному уникальному идентификатору GUID (globally unique identifier), определенному в файле dfwinty.f90:
    379

    О. В. Бартеньев. Современный ФОРТРАН
    type guid sequence integer*4 data1 integer*2 data2 integer*2 data3 character*8 data4 end type guid
    COM использует GUID для идентификации классов, интерфейсов и других требующих уникальных идентификаторов характеристик объекта.
    Чтобы создать экземпляр объекта, необходимо сообщить СОМ его
    (объекта) GUID. Также COM поддерживает программный идентификатор
    ProgID(programmatic identifier), имеющий вид: application_name.object_name.object_version
    Например: Excel.Application.8. Тип ProgID - CHARACTER(*).
    Соответствие между программным идентификатором и идентификатором класса устанавливается подпрограммой COMCLSIDFromProgID.
    12.5. Примеры работы с данными Автоматизации
    С Автоматизацией связаны специальные виды данных, например разнообразные константы, BSTR-строки, OLE-массивы или варианты, и процедуры, выполняющие с ними определенные действия, например размещение данных в памяти, изменение их значений или преобразование типов. В CVF эти данные определены в файле dfwinty.f90, а интерфейсы связанных с ними процедур - в файле oleaut32.f90. Собственно процедуры реализованы в файле oleaut32.dll.
    Для детального ознакомления с видами данных Автоматизации можно рекомендовать, например, приведенную в разд. 12.2 литературу. Здесь же приведем понятия OLE-массивов, BSTR-строк и вариантов, перечислим процедуры, работающие с этими объектами, и дадим ряд примеров.
    Заметим, что приводимые далее процедуры описаны также и в поставляемом с CVF файлом помощи.
    Навыки работы с данными Автоматизации нужны программисту, использующему COM-технологии, в частности, для того, чтобы обеспечить обмен данными между процедурами Фортрана и Автоматизации. При этом потребуется выполнять операции по преобразованию типов, например переходить от строки Фортрана к BSTR-строке, и данных, например передавать данные из массива Фортрана в OLE-массив.
    12.5.1. OLE-массивы
    Массивы, связанные с диспетчерским интерфейсом IDispatch, называются OLE-массивами. Их другое название - безопасные массивы.
    Внутри OLE-массива содержится информация о его ранге и форме. Для доступа к массиву используется его дескриптор, возвращаемый функцией
    380

    12. Конструктор модулей для объектов ActiveX
    SafeArrayCreate . Данные массива размещаются в памяти так же, как и данные массива Фортрана: быстрее всего изменяется самый первый индекс.
    В частности, в случае двумерного OLE-массива его данные размещаются в памяти компьютера по столбцам.
    С OLE-массивами связаны приведенные в табл. 12.3 функции. Все они имеют тип INTEGER(4).
    Таблица 12.3. Функции, работающие с OLE-массивами
    Функция
    Назначение
    SafeArrayAccessData
    Увеличивает счетчик блокировок массива и возвращает указатель на данные массива
    SafeArrayAllocData
    Выделяет память для OLE-массива, используя дескриптор, возвращенный SafeArrayAllocDescriptor
    SafeArrayAllocDescriptor
    Выделяет память для дескриптора массива
    SafeArrayCopy
    Копирует массив
    SafeArrayCopyData
    Копирует исходный массив в другой, предварительно освободив содержимое последнего
    SafeArrayCreate
    Создает новый дескриптор массива
    SafeArrayCreateVector
    Создает вектор заданного размера
    SafeArrayDestroy
    Разрушает дескриптор массива
    SafeArrayDestroyData
    Освобождает память, занятую массивом
    SafeArrayDestroyDescriptor Освобождает память, занятую дескриптором массива
    SafeArrayGetDim
    Возвращает ранг массива
    SafeArrayGetElement
    Возвращает элемент массива
    SafeArrayGetElemsize
    Возвращает размер элемента массива в байтах
    SafeArrayGetLBound
    Возвращает нижнюю границу для заданного измерения
    SafeArrayGetUBound
    Возвращает верхнюю границу для заданного измерения
    SafeArrayLock
    Увеличивает число блокировок массива
    SafeArrayPtrOfIndex
    Возвращает указатель на элемент массива
    SafeArrayPutElement
    Присваивает значение элементу массива
    SafeArrayRedim
    Изменяет правую, менее значимую границу массива
    SafeArrayUnaccessData
    Уменьшает счетчик блокировок массива и делает недействительным указатель, возвращенный
    SafeArrayAccessData
    SafeArrayUnlock
    Уменьшает счетчик блокировок массива
    381

    О. В. Бартеньев. Современный ФОРТРАН
    Пример. Первоначально создается OLE-массив, по форме совпадающий с массивом Фортрана a, затем данные из массива a переносятся в OLE- массив, после чего его содержимое отображается на экране. program SafeArrayTest use dfcomty
    ! Модуль ссылается на DFWINTY use dfcom
    ! Модуль ссылается на OLEAUT32 и DFWINTY implicit none integer(4) :: result, i, j, value integer(4) :: a(4, 3)
    ! Массив Фортрана type(sa_bounds) :: ab(2)
    ! Тип sa_bounds описан в модуле DFWINTY integer(4) :: indices(2) integer(4) :: safeArray
    ! OLE-массив
    ! Задание массива по столбцам a = reshape((/
    11, 12, 13,
    14,
    &
    ! Столбец 1 21, 22, 23,
    24,
    &
    !
    Столбец 2 31, 32, 33,
    34 /), shape = (/ 4, 3 /)) ! Столбец 3
    ! Формируем OLE-массив ab(1)%lbound = 1
    ! Нижняя граница по первому измерению ab(1)%extent = ubound(a, 1)
    ! Протяженность по первому измерению ab(2)%lbound = 1 ab(2)%extent = ubound(a, 2)
    ! Создаем новый дескриптор массива
    ! Константа VT_I4 описана в файле dfwinty.f90
    ! Она означает, что OLE-массив содержит 4-байтовые целые числа safeArray = SafeArrayCreate(VT_I4, 2, ab(1))
    ! Интерфейсы функций, работающих с OLE-массивами, см. в oleaut32.f90 do j = ab(2)%lbound, ab(2)%extent
    ! Переносим данные в OLE-массив do i = ab(1)%lbound, ab(1)%extent indices(1) = i; indices(2) = j
    ! Переносим данные из массива Фортрана в OLE-массив result = SafeArrayPutElement(safeArray, indices(1), loc(a(i, j))) end do end do do j = ab(2)%lbound, ab(2)%extent
    ! Читаем и выводим данные OLE-массива do i = ab(1)%lbound, ab(1)%extent indices(1) = i; indices(2) = j result = SafeArrayGetElement(safeArray, indices(1), loc(value)) write(*, '(i5)', advance = 'no') value
    ! Вывод без продвижения end do print *
    ! Переход на новую строку end do result = SafeArrayDestroy(safeArray) ! Освобождаем память end program SafeArrayTest
    382

    12. Конструктор модулей для объектов ActiveX
    Замечание. В модуле OLEAUT32 интерфейсы определены не для всех функций табл. 12.3. Однако при необходимости недостающий интерфейс можно записать самостоятельно.
    Пример. В программе OLE_vector создается интерфейс функции
    SafeArrayCreateVector, которая используется для формирования OLE- вектора. В вектор заносятся элементы строки string. program OLE_vector use dfwinty
    ! Для получения значения VT_UI1 use dfcom implicit none
    ! Опишем интерфейс SafeArrayCreateVector, поскольку его нет в модуле OLEAUT32 interface integer(4) function SafeArrayCreateVector(vt, lLbound, cElements)
    !dec$ attributes default, stdcall, alias :
    &
    '_SafeArrayCreateVector@' :: SafeArrayCreateVector
    !dec$ attributes value :: vt
    ! Все параметры передаются по значению
    !dec$ attributes value :: lLbound
    !dec$ attributes value :: cElements integer(4), intent(in) :: vt, lLbound , cElements end function SafeArrayCreateVector end interface integer(4) :: safeArray, len, i, indices(1), result character(30) :: string = 'Test string' character(1) :: ch len = len_trim(string)
    ! Длина строки string без завершающих пробелов
    ! Создаем новый дескриптор массива
    ! Константа VT_UI1 описана в файле dfwinty.f90
    ! Она означает, что OLE-массив содержит символы safeArray = SafeArrayCreateVector(VT_UI1, 1, len) do i = 1, len
    ! Заносим данные в OLE-вектор indices(1) = i result = SafeArrayPutElement(safeArray, indices(1), loc(string(i:i))) end do do i = 1, len
    ! Контрольный вывод indices(1) = i
    ! Читаем и выводим данные из OLE-вектора result = SafeArrayGetElement(safeArray, indices(1), loc(ch)) write(*, '(a)', advance = 'no') ch ! Вывод без продвижения end do print *
    ! Переход на новую строку end program OLE_vector
    12.5.2. BSTR-строки
    Строки, относящиеся к типам и структурам данных интерфейса IDis- patch, называются BSTR-строками. Эти строки завершаются нулевым символом (null) и предваряются целым числом, хранящим их длину. Внутри
    383

    О. В. Бартеньев. Современный ФОРТРАН
    строки также могут быть нулевые символы. Фактически BSTR - это указатель на строку. Его тип в Фортране - INTEGER(4).
    С BSTR-строками связаны приведенные в табл. 12.4 процедуры. Все они, кроме подпрограммы SysFreeString, являются функциями типа INTE-
    GER(4).
    Таблица 12.4. Процедуры для BSTR-строк
    Функция
    Назначение
    SysAllocString
    Размещает новую строку и копирует в нее строку-параметр
    SysAllocStringByteLen Принимает ANSI-строку и возвращает BSTR, эту строку содержащий
    SysAllocStringLen
    Размещает новую строку заданной длины и копирует в нее соответствующее число символов из строки-параметра
    SysFreeString
    (подпрограмма)
    Освобождает ранее размещенную строку
    SysReAllocString
    Изменяет размещение строки, копируя в нее передаваемые данные
    SysReAllocStringLen
    Изменяет размещение строки, копируя в нее заданное число символов
    SysStringByteLen
    Возвращает длину строки в байтах
    SysStringLen
    Возвращает длину строки
    VectorFromBSTR
    Возвращает OLE-вектор, каждый элемент которого равен соответствующему символу BSTR-строки
    BSTRFromVector
    Возвращает BSTR-строку, каждый символ которой равен соответствующему элементу OLE-вектора
    Замечания:
    1. Модуль DFCOM, размещенный в файле dfcom.f90, содержит функцию
    ConvertStringToBSTR, преобразовывающую строку Фортрана в BSTR, и функцию ConvertBSTRToString, выполняющую обратные преобразования.
    2. В модуле OLEAUT32 отсутствуют интерфейсы функций SysAllocString-
    ByteLen, VectorFromBSTR и BSTRFromVector.
    Пример. Формируется BSTR-строка, содержащая текст Test string. Далее она преобразовывается в строку Фортрана. program BSTR_example use dfcom integer(4) :: bstr, len character(30) :: string = 'Test string', string2 = ' ' bstr = ConvertStringToBSTR(string) ! Формируем BSTR-строку с текстом Test string
    ! Преобразовываем BSTR-строку в строку Фортрана
    384

    12. Конструктор модулей для объектов ActiveX len = ConvertBSTRToString(bstr, string2) print *, string2
    ! Test string end program BSTR_example
    12.5.3. Варианты
    Производный тип данных variant определен в файле dfwinty.f90: type variant sequence integer(2) vt integer(2) reserved1, reserved2, reserved3 record /variant_union/ vu end type variant
    Структура variant_union, использованная при формировании типа
    variant, имеет вид: structure /variant_union/
    ! Взята из файла dfwinty.f90 union map integer(4) long_val
    ! VT_I4 end map map character char_val
    ! VT_UI1 end map map integer(2) short_val
    ! VT_I2 end map map real(4) float_val
    ! VT_R4 end map map real(8) double_val
    ! VT_R8 end map map integer(2) bool_val
    ! VT_BOOL end map map integer(4) scode_val
    ! VT_ERROR end map map real(8) date_val
    ! VT_DATE end map map
    ! ptr_val - целочисленный указатель integer(4) ptr_val
    ! Для параметров, передаваемых по ссылке end map end union end structure
    385

    О. В. Бартеньев. Современный ФОРТРАН
    Тип variant широко распространен в Автоматизации; им, в частности, обладает подавляющее большинство параметров свойств и методов
    Автоматизации. Переменные типов variant называются вариантами.
    Варианты предназначаются для хранения данных разных типов и позволяют преобразовывать один тип в другой. Возможные типы, используемые с вариантами и другими объектами Автоматизации, задаются определенными в модуле DFWINTY целочисленными константами.
    Перечислим некоторые из них: integer(2), parameter :: vt_empty = 0
    ! Значение не задано integer(2), parameter :: vt_null = 1
    ! null integer(2), parameter :: vt_i2 = 2
    ! INTEGER(2) integer(2), parameter :: vt_i4 = 3
    ! INTEGER(4) integer(2), parameter :: vt_r4 = 4
    ! REAL(4) integer(2), parameter :: vt_r8 = 5
    ! REAL(8)
    ! Дата - число с плавающей точкой двойной точности integer(2), parameter :: vt_date = 7 integer(2), parameter :: vt_bstr = 8
    ! BSTR
    ! Указатель на объект, реализующий IDispatch integer(2), parameter :: vt_dispatch = 9 integer(2), parameter :: vt_error = 10
    ! Код ошибки integer(2), parameter :: vt_bool = 11
    ! Истина (#FFFF) или ложь (#0000) integer(2), parameter :: vt_variant = 12
    ! Указатель на вариант
    ! Указатель на объект, реализующий Iunknown integer(2), parameter :: vt_unknown = 13 integer(2), parameter :: vt_i1 = 16
    ! INTEGER(1) integer(2), parameter :: vt_ui1 = 17
    ! Целое без знака длиной в 1 байт integer(2), parameter :: vt_ui2 = 18
    ! Целое без знака длиной в 2 байта integer(2), parameter :: vt_ui4 = 19
    ! Целое без знака длиной в 4 байта
    Манипулировать вариантами позволяют приведенные в табл. 12.5 функции и подпрограмма. Тип функций - INTEGER(4).
    Таблица 12.5. Процедуры для вариантов
    Функция
    Назначение
    VariantChangeType
    Преобразовывает вариант в другой тип
    VariantChangeTypeEx
    Преобразовывает вариант в другой тип, используя идентификатор местности LCID, употребляемый при работе с разноязычными приложениями
    VariantClear
    Очищает вариант (освобождает память, занимаемую вариантом)
    VariantCopy
    Копирует вариант
    VariantCopyInd
    Копирует вариант, выполняя преобразование флага
    VT_BYREF, обеспечивающего передачу по ссылке, в
    BYVAL, что гарантирует передачу варианта по
    386

    12. Конструктор модулей для объектов ActiveX значению
    VariantInit (подпрограмма) Выполняет инициализацию варианта
    VariantTimeToDosDateTime Преобразовывает время, представленное в виде варианта, в дату и время в формате MSDOS
    VariantTimeToSystemTime
    Преобразовывает время, представленное в виде варианта, в системное представление времени
    Замечание. Модуль OLEAUT32 не содержит интерфейсы функция Variant-
    TimeToDosDateTime и VariantTimeToSystemTime.
    Пример. Создаются два варианта. Первый предназначается для хранения указателя BSTR, а второй - для 4-байтового вещественного числа. Каждый вариант получает соответствующее значение: первый - указатель на BSTR- строку "Компак Фортран", второй - число 6.1. Далее второй вариант преобразовывается в тип BSTR; оба варианта переводятся в строки
    Фортрана и выводится результат. program variant_example use dfcomty use dfcom use TextTransfer
    ! Для вывода русского текста в DOS-окно integer(4) :: status, length
    ! Код модуля TextTransfer см. в прил. 1 character(80) :: char1, char2 type(variant) v1, v2
    ! Тип variant описан в файле dfwinty.f90 call VariantInit(v1)
    ! Инициализация вариантов call VariantInit(v2) v1%vt = VT_BSTR
    ! Вариант v1 хранит BSTR-строку
    ! Преобразовываем строку Фортрана в строку BSTR
    ! Преобразовывающую функцию ConvertStringToBSTR см. в файле dfcom.f90 v1%vu%ptr_val = ConvertStringToBSTR("Компак Фортран") v2%vt = VT_R4
    ! 4-байтовое вещественное число v2%vu%float_val = 6.1
    ! Интерфейсы функций, работающих с вариантами, см. в oleaut32.f90
    ! Преобразовываем вариант v2 в BSTR-строку status = VariantChangeType(v2, v2, 0, VT_BSTR)
    ! Преобразовываем строки BSTR в строки Фортрана
    ! Преобразовывающую функцию ConvertBSTRToString см. в файле dfcom.f90 length = ConvertBSTRToString(v1%vu%ptr_val, char1) length = ConvertBSTRToString(v2%vu%ptr_val, char2) print *, trim(RuDosWin(trim(char1) // " " // trim(char2), .false.)) status = VariantClear(v1)
    ! Очищаем вариант status = VariantClear(v2) end program variant_example
    387

    О. В. Бартеньев. Современный ФОРТРАН
    12.6. Другие источники информации
    Технология взаимодействия с помощью СОМ, включающая в том числе и OLE-автоматизацию, подробно описана, кроме [14], в следующих источниках:

    How OLE and COM Solve the Problems of Component Software Design/by
    K. Brockschmidt//Microsoft Systems Journal. 1996. Vol. 11, N 5 (May).
    Р. 63-80.

    Inside OLE/Red. by K. Brockschmidt. 2d ed. Redmond; Washington: Micro- soft Press, 1995.

    OLE 2 Programmer's Reference, Vol. 2. Redmond; Washington: Microsoft
    Press, 1994.

    Understanding ActiveX and OLE/Red. by D. Chappell. Redmond; Washing- ton: Microsoft Press, 1996.

    Win 32 SDK, OLE Programmer's Reference online version.

    Win 32 SDK, Automation online version.

    http://mspress.microsoft.com/.
    12.7. Как воспользоваться объектом ActiveX
    Чтобы использовать объект ActiveX в Фортран-программе, необходимо выполнить следующие действия:

    найти существующий или установить новый объект в системе. Объект можно зарегистрировать специальной программой либо в результате его создания средствами Visual C++ или Visual Basic (см., например, документацию по DS);

    определить вид интерфейса, который объект имеет (в общем случае объект может иметь несколько интерфейсов), и используемые в объекте типы данных. Необходимые об объекте сведения добываются из связанной с ним документации. Также их можно получить, воспользовавшись имеющимся в DS средством просмотра объектов
    Автоматизации, вызов которого происходит в результате выполнения цепочки Tools - OLE/COM Object Viewer;

    применить КМ и получить код модуля, обеспечивающего доступ к объекту;

    написать программу на Фортране, в которой есть ссылки на полученный модуль и вызовы необходимых для работы с объектом процедур.
    12.8. Применение конструктора модулей
    Вызов КМ обеспечивает цепочка Tools - Fortran Module Wizard. После ее выполнения в появившемся окне (рис. 12.1) необходимо задать источник, из которого КМ получит данные об объекте.
    1   ...   38   39   40   41   42   43   44   45   ...   49


    написать администратору сайта