ЭТО НЕ ДУБЛИКАТ
Повторяющееся примечание о маркировке выше ^ неверно.
Как можно вызвать параметризованные методы библиотеки .NET(не зарегистрированный COM-объект) из программы Delphi 2010?
В частности, я хотел бы получить доступ к Saxon API, как описано здесь. В частности, я могу создать XsltCompiler и прочитать свойство BaseURI, но не устанавливать его.
У меня был некоторый успех с использованием COM-объектов Win32 COM (mscoree.dll и mscorlib.dll) и Late Binding. Это объясняется примером компонента Project-Jedi TJclClrHost. Я могу загружать сборки .NET, создавать объекты .NET и читать простые строковые свойства или функции без параметров. Мой вопрос: как передать параметры?
Этот вопрос проиллюстрирован задачей о том, как установить базовый URI XsltCompiler, загруженный из сборки Saxon.NET. API для BaseUri документирован здесь, существенная часть которого...
public Uri BaseUri {get; set; }
Используя отражение, я определил, что имя функции setter является "set_BaseUri".
Этот метод можно вызвать с помощью Late Binding/Reflection из библиотеки типов, импортированной из mscorlib.dll
. Ниже приведен соответствующий метод.
_Type = interface(IDispatch)
['{BCA8B44D-AAD6-3A86-8AB7-03349F4F2DA2}']
....
function InvokeMember(const name: WideString; invokeAttr: BindingFlags; const Binder: _Binder;
Target: OleVariant; args: PSafeArray; modifiers: PSafeArray;
const culture: _CultureInfo; namedParameters: PSafeArray): OleVariant; safecall;
...
end;
Что я пробовал до сих пор?
В моей программе Delphi 2010 я пишу..
FType.InvokeMember( 'set_BaseUri',
BindingFlags_Public or BindingFlags_Instance or BindingFlags_InvokeMethod or
BindingFlags_SetField or BindingFlags_SetProperty,
nil, FInstance, args, modifiers, nil, nil);
где: FType
имеет тип _Type
. args
и modifiers
являются и PSafeArray длины 1. Модификаторы должны быть массивом логических значений, чтобы сказать, передается ли аргумент по ссылке или передается по значению. В нашем случае это массив из одного логического значения со значением False (pass by value). args должен быть массивом фактических значений параметров.
Я пробовал все виды типов элементов массива, но я продолжаю получать ошибку. "Специфицированный массив не относится к ожидаемому типу".
Это мой код, чтобы установить args safeArray в некоторую строку.
var
args: PSafeArray;
argsbound: TSafeArrayBound;
PassByRef: boolean;
Idx: integer;
OValue: OleVariant;
begin
Idx := 0;
argsbound.cElements := 1;
argsbound.lLbound := 0;
args := SafeArrayCreate( VT_VARIANT, 1, argsbound);
OValue := 'www.abc.net.au';
SafeArrayPutElement( args, Idx, OValue);
...
Авеню, которые я изучил, но не являются решениями
- Хостинг CLR в Delphi с/без JCL - пример
- http://www.blong.com/Conferences/BorConUK2002/Interop2/COMNetInterop.htm
ЭТО НЕ ДУБЛИКАТ
ChrisF ошибочно отмечал это как дубликат. Связанный вопрос и ответы относятся только к ситуациям, когда разработчик контролирует и записывает сборку .Net. Как указано, сборка, пытающаяся быть вызванной, является третьей стороной (саксон). Вопрос был удовлетворительно дан, но он не должен был быть закрыт как дубликат.