С докой труднее... Лучше в виде вопрос-ответ.
Создание объекта.
Объектов может быть несколько. При освобождении объекта освобождаются библиотеки, им подгруженные.
- Код: Выделить всё
Set obj = CreateObject("DynamicWrapper")
Регистрация функции.
- Код: Выделить всё
obj.Register <имя DLL-файла>, <имя функции в DLL>, <дополнительные параметры>
где <дополнительные параметры> - это аргументы, которые могут быть расположены в разном порядке или вообще отсутствовать.
Дополнительные параметры.
<Псевдоним> - позволяет изменить имя функции по сравнению с существующим в DLL, чтобы исключить запрещенные знаки, дублирование имен, и просто для удобства.
<F-флаги> - строка вида "F={m|b}{s|c}{4|8}", определяющая способ вызова функции по такой таблице:
- Код: Выделить всё
const FLAGINFO FlagInfo[] =
{
{'m', DC_MICROSOFT, ~(DC_MICROSOFT|DC_BORLAND)},
{'b', DC_BORLAND, ~(DC_MICROSOFT|DC_BORLAND)},
{'s', DC_CALL_STD, ~(DC_CALL_STD|DC_CALL_CDECL)},
{'c', DC_CALL_CDECL, ~(DC_CALL_STD|DC_CALL_CDECL)},
{'4', DC_RETVAL_MATH4, ~(DC_RETVAL_MATH4|DC_RETVAL_MATH8)},
{'8', DC_RETVAL_MATH8, ~(DC_RETVAL_MATH4|DC_RETVAL_MATH8)},
};
Если не указана, считается "F=ms".
<I-флаги> - строка вида "I=<символы типов аргумента>", определяющая способ передачи/приема аргументов функции по такой таблице:
- Код: Выделить всё
const ARGTYPEINFO ArgInfo[] =
{
{'c', sizeof(unsigned char), VT_UI1}, // BYTE или Byte
{'i', sizeof(short), VT_I2}, // SHORT или Integer
{'l', sizeof(long), VT_I4}, // LONG или Long
{'h', sizeof(long), VT_I4}, // HANDLE или Long
{'u', sizeof(UINT), VT_I4}, // UINT или Long
{'f', sizeof(float), VT_R4}, // FLOAT или Single
{'d', sizeof(double), VT_R8}, // DOUBLE или Double
{'b', sizeof(VARIANT_BOOL), VT_BOOL}, // VARIANT_BOOL или Boolean
{'k', sizeof(IUnknown*), VT_UNKNOWN}, // LPUNKNOWN или ???
{'o', sizeof(IDispatch*), VT_DISPATCH},// LPDISPATCH или Object
{'s', sizeof(LPSTR), VT_LPSTR}, // string или String
{'r', sizeof(LPSTR), VT_LPSTR}, // out string same as S
{'w', sizeof(LPWSTR), VT_LPWSTR}, // wstring или String
{'v', sizeof(VARIANT), VT_VARIANT}, // VARIANT или Variant
{'t', sizeof(DATE), VT_DATE}, // DATE или Date
{'p', sizeof(void*), VT_BYREF}, // generic pointer
};
Если не указана или указана "I=", то считается, что аргументов нет.
Дополнительно после основного типа можно указывать модификатор типа:
'*' - указатель на значение, т.е. L* - указатель на целое число. Пример:
- Код: Выделить всё
obj.Register "Advapi32.DLL", "RegOpenKey", "OpenKey", "F=MS", "I=HSH*", "R=L"
'#' - массив значений, т.е. L# - массив целых чисел. Но передавать можно массив другого типа. Примера у меня нет, чтобы показать, но сам я использую для С-шных массивов. Вроде работает.
<R-флаги> - строка вида "R=<символ типа>", определяющая возвращаемое значение функции (см. I-флаги). Если не указана или указана "R=", считается, что нет возвращаемого значения.