如何从Delphi调用.NET?

Sea*_*kin 11 .net delphi

这不是重复的

上面的重复标记说明^是错误的.

如何从Delphi 2010程序中调用.NET库(不是已注册的COM对象)的参数化方法?

具体来说,我想访问Saxon API,如此处所述.具体来说,我可以创建一个XsltCompiler并读取BaseURI属性,但不能设置它.

我使用Win32 COM服务器对象(mscoree.dll和mscorlib.dll)和Late Binding取得了一些成功.这要归功于Project-Jedi TJclClrHost组件的示例.我可以加载.NET程序集,创建.NET对象并读取没有参数的简单字符串属性或函数.我的问题是如何传递参数?

这个问题的例子是如何设置从Saxon .NET程序集加载的XsltCompiler的基本URI.这里记录了BaseUri的API ,其中显着的部分是......

public Uri BaseUri {get; set; }
Run Code Online (Sandbox Code Playgroud)

使用反射,我已经确定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;
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试了什么?

在我的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);
Run Code Online (Sandbox Code Playgroud)

其中: 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);
...
Run Code Online (Sandbox Code Playgroud)

我已经研究过的途径,但不是解决方案

这不是重复的

ChrisF将此标记为重复是错误的.引用的问题和答案仅涉及开发人员控制和编写.Net程序集的情况.如上所述,试图被调用的程序集是第三方(Saxon).这个问题得到了令人满意的答复,但它不应该作为副本被关闭.

Jim*_*eth 3

我不太熟悉 Saxon API,但我熟悉 Delphi、.NET 和 COM 互操作性。

我建议您用您最喜欢的(或最容易接受的).NET 语言围绕 Saxon API创建一个外观模式。在这些包装类上保留 ComVisible True。然后通过 Delphi 中的COM Interop访问此包装器程序集。

您确实可以摆脱适配器模式,但由于我假设您不需要访问整个 Saxon API,因此外观更合适。