Dot-Net

如何從 Delphi 呼叫 .NET?

  • July 12, 2017

這不是重複的

^ 上面的重複標記註釋是錯誤的。

如何從 Delphi 2010 程序呼叫 .NET 庫(不是註冊的 COM 對象)的參數化方法?

具體來說,我想訪問 Saxon API,如此所述。具體來說,我可以創建一個 XsltCompiler 並讀取 BaseURI 屬性,但不設置它。

我使用 Win32 COM 伺服器對象(mscoree.dll 和 mscorlib.dll)和後期綁定取得了一些成功。這要歸功於 Project-Jedi TJclClrHost 組件的範例。我可以載入 .NET 程序集、創建 .NET 對象並讀取簡單的字元串屬性或不帶參數的函式。我的問題是如何傳遞參數?

這個問題通過如何設置從 Saxon .NET 程序集載入的 XsltCompiler 的 Base URI 的任務來舉例說明。BaseUri 的 API 記錄在這裡,其中最突出的部分是……

public Uri BaseUri {get; set; }

使用反射,我確定 setter 函式的名稱是“set_BaseUri”。

可以使用從導入的類型庫中的後期綁定/反射呼叫此方法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是 類型_Typeargs並且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 將其標記為重複是錯誤的。引用的問題和答案僅涉及開發人員控制和編寫 .Net 程序集的情況。如前所述,試圖呼叫的程序集是第三方(Saxon)。該問題已得到令人滿意的回答,但不應作為重複而關閉。

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

我建議你做的是用你最喜歡的(或最能容忍的).NET 語言圍繞 Saxon API創建一個外觀模式。在這些包裝類上保留 ComVisible True。然後通過Delphi 中的COM Interop訪問這個包裝程序集。

您真的可以使用適配器模式,但由於我假設您不需要訪問整個 Saxon API,因此外觀更合適。

引用自:https://stackoverflow.com/questions/16785357