Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Внешние компоненты в 1С 8.2

Anna | 24.06.2014 | нет комментариев
Эта статья дает представление о работе внешних компонент в системе «1С: Предприятие».
Будет показан процесс разработки внешней компоненты для системы «1С: Предприятие» версии 8.2, работающей под управлением ОС семейства Windows с файловым вариантом работы. Такой вариант работы применяется в большинстве решений, предуготовленных для предприятий малого бизнеса. ВК будет реализована на языке программирования C .

Внешние компоненты «1C: Предприятие»

«1С: Предприятие» является расширяемой системой. Для растяжения функциональных вероятностей системы применяются внешние компоненты (ВК). С точки зрения разработчика ВК представляет собой определенный внешний объект, тот, что имеет свойства и способы, а также может генерировать события для обработки системой «1С: Предприятие».
Внешние компоненты дозволено применять для решения класса задач, которые трудно либо даже немыслимо реализовать на встроенном в «1C: Предприятие» языке программирования. В частности, к такому классу дозволено отнести задачи, требующие низкоуровневого взаимодействия с операционной системой, скажем, для работы с специфичным оборудованием.
В системе «1С: Предприятие» применяются две спецтехнологии создания внешних компонент:

  • с применением Native API
  • с применением спецтехнологии COM

При заданных ограничениях между двумя вышеозначенными спецтехнологиями разница незначительна, следственно будем рассматривать разработку ВК с применением Native API. При необходимости, реализованные наработки могут быть применены для разработки ВК с применением спецтехнологии COM, а также, с незначительными доработками, применены для применения в системе «1С: Предприятие» с другими вариантами работы, чудесными от файлового режима работы.

Конструкция ВК

Внешняя компонента системы «1С: Предприятие» представлена в виде DLL-библиотеки. В коде библиотеки описывается класс-преемник IComponentBase. В создаваемом классе обязаны быть определены способы, отвечающие за реализацию функций внешней компоненты. Больше детально переопределяемые способы будут описаны ниже по ходу изложения материала.

Запуск демонстрационной ВК

Задача:

  1. Исполнить сборку внешней компоненты, поставляемой с подпиской ИТС и предуготовленной для демонстрации основных вероятностей механизма внешних компонент в 1С
  2. Подключить демонстрационную компоненту к конфигурации 1С
  3. Удостовериться в правильной работоспособности заявленных функций
Компиляция

Демонстрационная ВК расположена на диске подписки ИТС в каталоге «/VNCOMP82/example/NativeAPI».
Для сборки демонстрационной ВК будем применять Microsoft Visual Studio 2008. Другие версии данного продукта не поддерживают применяемый формат плана Visual Studio.

Открываем план AddInNative. В настройках плана подключаем каталог с заголовочными файлами, нужными для сборки плана. По умолчанию они располагаются на диске ИТС в каталоге /VNCOMP82/include.
Итогом сборки является файл /bind/AddInNative.dll. Это и есть скомпилированная библиотека для подключения к конфигурации 1С.

Подключение ВК к конфигурации 1С

Сотворим пустую конфигурацию 1С.
Ниже приведен код модуля управляемого приложения.

перем ДемоКомп;
Процедура ПриНачалеРаботыСистемы()
	ПодключитьВнешнююКомпоненту("...bindAddInNative.dll", "DemoVK", ТипВнешнейКомпоненты.Native);
	ДемоКомп = Новейший("AddIn.DemoVK.AddInNativeExtension");
КонецПроцедуры

Если при запуске конфигурации 1С не было извещено об ошибке, то ВК была удачно подключена.
В итоге выполнения приведенного кода в всеобщей видимости конфигурации возникает объект ДемоКомп, имеющий свойства и способы, которые определены в коде внешней компоненты.

Демонстрация заложенного функционала

Проверим работоспособность демонстрационной ВК. Для этого испробуем установить и прочитать некоторые свойсмер свойства, имя которого передается в параметрах
GetPropName
Возвращает имя свойства по его порядковому номеру и по переданному идентификатору языка
GetPropVal
Возвращает значение свойства с указанным порядковым номером
SetPropVal
Устанавливает значение свойства с указанным порядковым номером
IsPropReadable
Возвращает флаг флаг вероятности чтения свойства с указанным порядковым номером
IsPropWritable
Возвращает флаг флаг вероятности записи свойства с указанным порядковым номером

Полное изложение способов, включая список параметров детально описан в документации, поставляемой на диске ИТС.
Разглядим реализацию приведенных способов класса CAddInNative.
В демонстрационной ВК определены 2 свойства: Включен и ЕстьТаймер (IsEnabled и IsTimerPresent).
В всеобщей области видимости кода библиотеки определено два массива:

static wchar_t *g_PropNames[] = {L"IsEnabled", L"IsTimerPresent"};
static wchar_t *g_PropNamesRu[] = {L"Включен", L"ЕстьТаймер"};

которые хранят русское и английское наименования свойств. В заголовочном файле AddInNative.hопределяется перечисление:

enum Props
    {
        ePropIsEnabled = 0,
        ePropIsTimerPresent,
        ePropLast      // Always last
    };

ePropIsEnabled и ePropIsTimerPresent, соответственно имеющие значения 0 и 1 применяются для замены порядковых номеров свойств на осмысленные идентификаторы. ePropLast, имеющее значение 2, применяется для приобретения числа свойств (способом GetNProps). Эти имена применяются только внутри кода компоненты и недостижимы извне.
Способы FindProp и GetPropName осужествляют поиск по массивам g_PropNames и g_PropNamesRu.
Для хранения значения полей в модуле библиотеки у класса CAddInNative определены свойства, которые хранят значение свойств компоненты. Способы GetPropVal и SetPropVal соответственно возвращают и устанавливают значение этих свойств.
Способы IsPropReadable и IsPropWritable и возвращают trure либо false, в зависимости от переданного порядкового номера свойства в соответствии с логикой приложения.
Для того, Дабы добавить произвольное качество нужно:

  1. Добавить имя добавляемого свойства в массивы g_PropNames и g_PropNamesRu (файлAddInNative.cpp)
  2. В перечисление Props (файл AddInNative.h) перед ePropLast добавить имя, однозначно идентифицирующее добавляемое качество
  3. Организовать память под хранение значений свойств (завести поля модуля компоненты, хранящие соответствующие значения)
  4. Внести метаморфозы в способы GetPropVal и SetPropVal для взаимодействия с выделенной на предыдущем шаге памятью
  5. В соответствии с логикой приложения внести метаморфозы в способы IsPropReadable и IsPropWritable

Пункты 1, 2, 5 не нуждаются в пояснении. С деталями реализации этих шагов дозволено ознакомиться, изучив приложение к статье.
Дадим наименования тестовым свойствам Тест и ПроверкаТипа соответственно. Тогда в итоге выполнения пункта 1 имеем:

static wchar_t *g_PropNames[] = {L"IsEnabled", L"IsTimerPresent", L"Test", L"TestType"};
static wchar_t *g_PropNamesRu[] = {L"Включен", L"ЕстьТаймер", L"Тест", L"ПроверкаТипа"};

Перечисление Props будет иметь вид:

 enum Props
    {
        ePropIsEnabled = 0,
        ePropIsTimerPresent,
		ePropTest1,
		ePropTest2,
        ePropLast      // Always last
    };

Для существенного облегчения кода будем применять STL C . В частности, для работы со строками WCHAR, подключим библиотеку wstring.
Для сохранения значения способа Тест, определим в классе CAddInNative в области видимости private поле:

string test1;

Для передачи строковых параметров между «1С: Предприятие» и внешней компонентов применяется администратор памяти «1С: Предприятие». Разглядим его работу подробнее. Для выделения и освобождения памяти соответственно применяются функции AllocMemory и FreeMemory, определенные в файлеImemoryManager.h. При необходимости передать системе «1С: Предприятие» строковый параметр, внешняя компонента должна выделить под нее память вызовом функции AllocMemory. Ее прототип выглядит дальнейшим образом:

virtual bool ADDIN_API AllocMemory (void** pMemory, unsigned long ulCountByte) = 0;

где pMemory — адрес указателя, в тот, что будет размещен адрес выделенного участка памяти,
ulCountByte — размер выделяемого участка памяти.
Пример выделения памяти под строку:

WCHAR_T *t1 = NULL, *test = L"TEST_STRING";
int iActualSize = wcslen(test1) 1;
m_iMemory->AllocMemory((void**)&t1, iActualSize * sizeof(WCHAR_T));
::convToShortWchar(&t1, test1, iActualSize);

Для комфорта работы с строковыми типами данными опишем функцию wstring_to_p. Она получает в качестве параметра wstring-строку. Итогом функции является заполненная конструкция tVariant. Код функции:

bool CAddInNative::wstring_to_p(std::wstring str, tVariant* val) {
	char* t1;
	TV_VT(val) = VTYPE_PWSTR;
	m_iMemory->AllocMemory((void**)&t1, (str.length() 1) * sizeof(WCHAR_T));
	memcpy(t1, str.c_str(), (str.length() 1) * sizeof(WCHAR_T));
	val -> pstrVal = t1;
	val -> strLen = str.length();
	return true;
}

Тогда соответствующая сегмент case оператора switch способа GetPropVal примет вид:

case ePropTest1:
	wstring_to_p(test1, pvarPropVal);
	break;

Способа SetPropVal:

 case ePropTest1:
	if (TV_VT(varPropVal) != VTYPE_PWSTR)
		 return false;
	test1 = std::wstring((wchar_t*)(varPropVal -> pstrVal));
	break;

Для реализации второго свойства определим поле класса CaddInNative

uint8_t				last_type;

в котором будем сберегать тип последнего переданного значения. Для этого в способ CaddInNative::SetPropVal добавим команду:

last_type = TV_VT(varPropVal);

Сейчас при запросе чтения значения второго свойства будем возвращать значение last_type, чего требует обозначенное задание.
Проверим работоспособность произведенных изменений.
Для этого приведем внешний вид конфигурации 1С к виду:

перем ДемоКомп;
Процедура ПриНачалеРаботыСистемы()
	ПодключитьВнешнююКомпоненту("...", "DemoVK", ТипВнешнейКомпоненты.Native);
	ДемоКомп = Новейший("AddIn.DemoVK.SomeName");
	ДемоКомп.ПроверкаТипа = 1;
	Сообщить(Строка(ДемоКомп.ПроверкаТипа));
	ДемоКомп.Тест = "Вася";
	Сообщить(Строка(ДемоКомп.Тест));
	ДемоКомп.Тест = "Петя";
	Сообщить(Строка(ДемоКомп.Тест));
	Сообщить(Строка(ДемоКомп.ПроверкаТипа));
КонецПроцедуры

В итоге запуска получим последовательность сообщений:
3
Вася
Петя
22

Второе и третье сообщения являются итогом чтения свойства, установленного на предыдущем шаге. Первое и второе сообщения содержат код типа последнего установленного свойства. 3 соответствует целочисленному значению, 22 — строковому. Соответствие типов и их кодов устанавливается в файле types.h, тот, что находится на диске ИТС.

Растяжение списка способов

Задача:

  1. Расширить функционал внешней компоненты дальнейшим функционалом:
  2. Исследовать методы реализации способов внешней компоненты
  3. Добавить способ-функцию Функц1, которая в качестве параметра принимает две строки («Параметр1» и «Параметр2»). В качестве итога возвращается строка вида: «Проверка. Параметр1, Параметр2»
  4. Удостовериться в работоспособности произведенных изменений

Для определения способов создаваемой компоненты разработчику нужно реализовать следующие способы в коде библиотеки AddInNative:
GetNMethodsFindMethodGetMethodName
Предуготовлены для приобретения соответственно числа способов, поиска номера и имени способа. Аналогичны соответствующим способам для свойств
GetNParams
Возвращает число параметров способа с указанным порядковым номером; если способ с таким номером отсутствует либо не имеет параметров, возвращает 0
GetParamDefValue
Возвращает значение по умолчанию указанного параметра указанного способа
HasRetVal
Возвращает флаг наличия у способа с указанным порядковым номером возвращаемого значения: true для способов с возвращаемым значением и false в отвратном случае
CallAsProc
Исполняет способ с указанным порядковым номером. Если способ возвращает false, появляется оплошность времени выполнения и выполнение модуля 1С: Предприятия прекращается. Память для массива параметров выдается и освобождается 1С: Предприятием.
CallAsFunc
Исполняет способ с указанным порядковым номером. Если способ возвращает false, появляется оплошность времени выполнения и выполнение модуля 1С: Предприятия прекращается. Память для массива параметров выдается 1С: Предприятием. Если возвращаемое значение имеет тип строка либо двоичные данные, компонента выделяет память функцией AllocMemory администратора памяти, записывает туда данные и сберегает данный адрес в соответствующем поле конструкции. 1С: Предприятие освободит эту память вызовом FreeMemory.
Полное изложение способов, включая список параметров детально описан в документации, поставляемой на диске ИТС.
Разглядим реализацию описанных выше способов.
В в коде компоненты определены два массива:

static wchar_t *g_MethodNames[] = {L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"};
static wchar_t *g_MethodNamesRu[] = {L"Включить", L"Отключить", L"ПоказатьВСтрокеСтатуса", L"СтартТаймер", L"СтопТаймер", L"ЗагрузитьКартинку"};

и перечисление:

enum Methods
    { 
        eMethEnable = 0,
        eMethDisable,
        eMethShowInStatusLine,
        eMethStartTimer,
        eMethStopTimer,
        eMethLoadPicture,
        eMethLast      // Always last
    };

Они применяются в функциях GetNMethodsFindMethod и GetMethodName, по аналогии с изложением свойств.
Способы GetNParamsGetParamDefValueHasRetVal реализуют switch, в зависимости от переданных параметров и логики приложения возвращают требуемое значение. Способ HasRetVal в своем коде имеет список только способов, которые могут возвращать итог. Для них он возвращает true. Для всехо стальных способов возвращается false.
Способы CallAsProc и CallAsFunc содержат непринужденно исполняемый код способа.
Для добавления способа, тот, что может вызываться только как функция нужно произвести следующие метаморфозы в начальном коде внешней компоненты:

  1. Добавить имя способа в массивы g_MethodNames и g_MethodNamesRu (файл AddInNative.cpp)
  2. Добавить осмысленный идентефикатор способа в перечисление Methods (файл AddInNative.h)
  3. Внести метаморфозы в код функции GetNParams в соответствии с логикой программы
  4. При необходимости внести метаморфозы в код способа GetParamDefValue, если требуется применять значения по умолчанию параметров способа.
  5. Внести метаморфозы в функцию HasRetVal
  6. Внести метаморфозы в логику работы функций CallAsProc либо CallAsFunc, разместив туда непринужденно исполняемый код способа

Приведем массивы g_MethodNames и g_MethodNamesRu, а также перечисление Methods к виду:

static wchar_t *g_MethodNames[] = {L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test"};
static wchar_t *g_MethodNamesRu[] = {L"Включить", L"Отключить", L"ПоказатьВСтрокеСтатуса", L"СтартТаймер", L"СтопТаймер", L"ЗагрузитьКартинку", L"Тест"};
 enum Methods
    {
        eMethEnable = 0,
        eMethDisable,
        eMethShowInStatusLine,
        eMethStartTimer,
        eMethStopTimer,
        eMethLoadPicture,
		eMethTest,
        eMethLast      // Always last
    };

Отредактируем функцию GetNProps, Дабы она возвращала число параметров способа «Тест»:

long CAddInNative::GetNParams(const long lMethodNum)
{ 
    switch(lMethodNum)
    { 
    case eMethShowInStatusLine:
        return 1;
    case eMethLoadPicture:
        return 1;
    case eMethTest:
        return 2;
	default:
        return 0;
    }
return 0;
}

Внесем метаморфозы в функцию CAddInNative::GetParamDefValue:

bool CAddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue)
{ 
    TV_VT(pvarParamDefValue)= VTYPE_EMPTY;
    switch(lMethodNum)
    { 
    case eMethEnable:
    case eMethDisable:
    case eMethShowInStatusLine:
    case eMethStartTimer:
    case eMethStopTimer:
	case eMethTest:
        // There are no parameter values by default 
        break;
    default:
        return false;
    }
    return false;
} 

Вследствие добавленной строке

case eMethTest:

в случае отсутствия одного либо нескольких доводов соответствующие параметры будут иметь пустое значение (VTYPE_EMPTY). Если нужно присутствие значения по умолчанию для параметра, следует задать его в сегменты eMethTest оператора switch функции CAddInNative::GetParamDefValue.
Так как способ «Тест» может возвращать значение, нужно внести метаморфозы в код функции HasRetVal:

bool CAddInNative::HasRetVal(const long lMethodNum)
{ 
    switch(lMethodNum)
    { 
    case eMethLoadPicture:
	case eMethTest:
        return true;
    default:
        return false;
    }
    return false;
}

И добавим исполняемый код способа в функцию CallAsFunc:

bool CAddInNative::CallAsFunc(const long lMethodNum,
                tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray)
{ 
...
std::wstring s1, s2;
    switch(lMethodNum)
    {
    case eMethLoadPicture:
	   ...
        break;
	case eMethTest:
        if (!lSizeArray || !paParams)
            return false;
	    s1 = (paParams) -> pwstrVal;
	    s2 = (paParams 1) -> pwstrVal;
	    wstring_to_p(std::wstring(s1 s2), pvarRetValue);
	    ret = true;
	    break;
    }
    return ret; 
}

Скомпилируем компоненту и приведем код конфигурации к виду:

перем ДемоКомп;
Процедура ПриНачалеРаботыСистемы()
	ПодключитьВнешнююКомпоненту("...", "DemoVK", ТипВнешнейКомпоненты.Native);
	ДемоКомп = Новейший("AddIn.DemoVK.SomeName");
	пер = ДемоКомп.Тест("Здравствуй, ", "Мир!");
	Сообщить(пер);
КонецПроцедуры 

Позже запуска конфигурации получим сообщение: «Здравствуй, Мир!», что говорит о том, что способ отработал удачно.

Таймер

Задача:

  1. Исследовать реализацию таймера в демонстрационной ВК
  2. Модифицировать способ «СтартТаймер», добавив вероятность передавать в параметрах промежуток срабатывания таймера (в миллисекундах)
  3. Удостовериться в работоспособности произведенных изменений

В WinAPI для работы со временем дозволено воспользоваться сообщением WM_TIMER. Данное сообщение будет посылаться вашей программе через промежуток времени, тот, что вы зададите при создании таймера.
Для создания таймера применяется функция SetTimer:

UINT SetTimer(HWND hWnd,              // описатель окна
UINT nIDevent,          // идентификатор (номер) таймера
              UINT nElapse,           // задержка
              TIMERPROC lpTimerFunc); // указатель на функцию

Операционная система будет посылать сообщение WM_TIMER в программу с промежутком указанным в доводе nElapse (в миллисекундах). В последнем параметре дозволено указать функцию, которая будет выполняться при всяком срабатывании таймера. Заголовок этой функции должен выглядеть так (имя может быть любым):

void __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)

Разглядим реализацию таймера в демонстрационной ВК.
Так как мы рассматриваем процесс разработки внешней компоненты для ОС семейства Windows, не будем рассматривать реализацию таймера в других операционных системах. Для ОС GNU/Linux, в частности, реализация будет отличаться синтаксисом функции SetTimer и TimerProc.
В исполняемом коде вызывается способ SetTimer, в тот, что передается функция MyTimerProc:

m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);

Идентефикатор сделанного таймера помещается в переменную m_uiTimer, Дабы в последствии его дозволено было отключить.
Функция MyTimerProc выглядит дальнейшим образом:

VOID CALLBACK MyTimerProc(
  HWND hwnd,    // handle of window for timer messages
  UINT uMsg,    // WM_TIMER message
  UINT idEvent, // timer identifier
  DWORD dwTime  // current system time
)
{
    if (!pAsyncEvent)
        return;
    wchar_t *who = L"ComponentNative", *what = L"Timer";
    wchar_t *wstime = new wchar_t[TIME_LEN];
    if (wstime)
    {
        wmemset(wstime, 0, TIME_LEN);
        ::_ultow(dwTime, wstime, 10);
        pAsyncEvent->ExternalEvent(who, what, wstime);
        delete[] wstime;
    }
}

Суть функции сводится к тому, что вызывается способ ExternalEvent, тот, что посылает сообщение системе «1С: Предприятие».
Для растяжения функционала способа СтартТаймер произведем следующие действия:
Модифицируем код способа GetNParams так, Дабы он для способа eMethStartTimer возвращал значение 1:

case eMethStartTimer:
	return 1;

Приведем код способа CallAsProc к виду:

case eMethStartTimer:
	if (!lSizeArray || TV_VT(paParams) != VTYPE_I4 || TV_I4(paParams) <= 0)
		return false;
	pAsyncEvent = m_iConnect;
#ifndef __linux__
        m_uiTimer = ::SetTimer(NULL,0,TV_I4(paParams),(TIMERPROC)MyTimerProc);
#else
// код для GNU/Linux
#endif
	break;

Сейчас проверим работоспособность. Для этого в модуле управляемого приложения конфигурации напишем код:

перем ДемоКомп;
Процедура ПриНачалеРаботыСистемы()
	ПодключитьВнешнююКомпоненту("...", "DemoVK", ТипВнешнейКомпоненты.Native);
	ДемоКомп = Новейший("AddIn.DemoVK.SomeName");
	ДемоКомп.СтартТаймер(2000);
КонецПроцедуры  

Позже запуска конфигурации в программу будут поступать сообщения с промежутком в 2 секунды, что говорит о правильной работе таймера.

Взаимодействие с системой «1С: Предприятие»

Для взаимодействия между внешней компонентой и системой «1С: Предприятие» применяются способы класса IAddInDefBase, описанного в файле AddInDefBase.h. Перечислим особенно Зачастую используемые:
Генерация сообщения об ошибке

virtual bool ADDIN_API AddError(unsigned short wcode, const WCHAR_T* source, const WCHAR_T* descr, long scode)

wcodescode — коды ошибки (список кодов ошибок с изложением дозволено обнаружить на диске ИТС)
source — источник ошибки
descr — изложение ошибки
Отправка сообщения системе «1С: Предприятие»

virtual bool ADDIN_API ExternalEvent(WCHAR_T* wszSource, WCHAR_T* wszMessage, WCHAR_T* wszData) = 0;

wszSource — источник сообщения
wszMessage — текст сообщения
wszData — передаваемые данные
Перехват сообщения осуществляется процедурой ОбработкаВнешнегоСобытия
Регистрация внешней компоненты в системе «1С: Предприятие»

virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)

wszProfileName — имя компоненты.
Этих способов довольно для полновесного взаимодействия ВК и 1С. Для приобретения данных внешней компонентой от системы «1С: Предприятие» и напротив внешняя компонента отправляет особое сообщение, которое в свою очередь перехватывается системой «1С» и, при необходимости вызывает способы внешней компоненты для обратной передачи данных.

Тип данных tVariant

При обмене данными между внешней компонентой и системой «1С: Предприятие» применяется тип данных tVariant. Он описан в файле types.h, тот, что дозволено обнаружить на диске с ИТС:

struct _tVariant 
{ 
    _ANONYMOUS_UNION union 
    { 
        int8_t         i8Val; 
        int16_t        shortVal; 
        int32_t        lVal; 
        int            intVal; 
        unsigned int   uintVal; 
        int64_t        llVal; 
        uint8_t        ui8Val; 
        uint16_t       ushortVal; 
        uint32_t       ulVal; 
        uint64_t       ullVal; 
        int32_t        errCode; 
        long           hRes; 
        float          fltVal; 
        double         dblVal; 
        bool           bVal; 
        char           chVal; 
        wchar_t        wchVal; 
        DATE           date; 
        IID            IDVal; 
        struct _tVariant *pvarVal; 
        struct tm      tmVal; 
        _ANONYMOUS_STRUCT struct 
        { 
            void*  pInterfaceVal; 
            IID        InterfaceID; 
        } __VARIANT_NAME_2/*iface*/; 
        _ANONYMOUS_STRUCT struct 
        { 
            char*        pstrVal; 
            uint32_t     strLen; //count of bytes 
        } __VARIANT_NAME_3/*str*/; 
        _ANONYMOUS_STRUCT struct 
        { 
            WCHAR_T*    pwstrVal; 
            uint32_t    wstrLen; //count of symbol 
        } __VARIANT_NAME_4/*wstr*/; 
    } __VARIANT_NAME_1; 
    uint32_t      cbElements;    //Dimension for an one-dimensional array in pvarVal 
    TYPEVAR       vt; 
}; 

Тип tVariant представляет из себя структру, которая включает себя:

  • смесь (union), предуготовленную непринужденно для хранения данных
  • идентификатор типа данных

В всеобщем случае работа с переменными типа tVariant происходит по дальнейшему алгорифму:

  1. Определение типа данных, которые в данный момент хранятся в переменной
  2. Обращение к соответствующему полю смеси, для непосредственного доступа к данным

Применение типа tVariant гораздо упрощает взаимодействие системы «1С: Предприятие» и внешней компоненты

Приложение

Каталог «examples» содержит примеры к статье
examples/1 — запуск демонстрационной компоненты
examples/2 — демонстрация растяжения списка свойств
examples/3 — демонстрация растяжения списка способов
Всякий каталог содержит план VS 2008 и готовую конфигурацию 1C.
Скачать приложение

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB