上面的重复标记说明^错误。
如何从Delphi 2010程序中调用.NET库的参数化方法(不是已注册的COM对象)?
具体来说,我想访问Saxon API,记录为here。具体来说,我可以创建一个XsltCompiler并读取BaseURI属性,但不能设置它。
我使用Win32 COM服务器对象(mscoree.dll和mscorlib.dll)和Late Binding取得了一些成功。这要归功于Project-Jedi TJclClrHost组件的示例。我可以加载.NET程序集,创建.NET对象并读取没有参数的简单字符串属性或函数。我的问题是如何传递参数?
这个问题的例子是如何设置从Saxon .NET程序集加载的XsltCompiler的基本URI。 BaseUri的API记录在案here,其中显着部分是......
public Uri BaseUri {get; set; }
使用反射,我已经确定setter函数的名称是'set_BaseUri'。
可以使用从mscorlib.dll
导入的类型库中的Late Binding / Reflection调用此方法。相关方法如下所列。
_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
都是长度为1的PSafeArray。修饰符应该是一个布尔数组,用于说明参数是通过引用传递还是传递值。在我们的例子中,这是一个布尔值的数组,其值为False(按值传递)。 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);
...
ChrisF将此标记为duplicate是错误的。引用的问题和答案仅涉及开发人员控制和编写.Net程序集的情况。如上所述,试图被调用的程序集是第三方(Saxon)。这个问题得到了圆满的回答,但它不应该作为副本被关闭。
答案 0 :(得分:3)
对Saxon API并不十分熟悉,但我熟悉Delphi,.NET和COM互操作性。
我建议你做的是在你最喜欢的(或最容忍的).NET语言中围绕Saxon API创建一个facade pattern。在这些包装类上保留ComVisible True。然后通过Delphi中的COM Interop访问此包装程序集。
你真的可以使用adapter patter,但由于我假设您不需要访问整个Saxon API,因此外观更合适。