項目需發送激活郵件,郵件含用戶密碼,密碼由 C# TripleDES 加密。因時間緊迫,無暇移植算法到 Delphi,決定將 C# 邏輯封裝為 COM 可見組件,Delphi 通過 CreateOleObject 晚綁定調用。
DotNetFunc.cs):定義 EncryptTripleDES/DecryptTripleDES 方法,標記 [ComVisible(true)]、[ClassInterface(ClassInterfaceType.AutoDual)]、[Guid(...)]。sn -k key.snkcsc /t:library /keyfile:key.snk DotNetFunc.cs (產生 DotNetFunc.dll)tlbexp DotNetFunc.dll /out:DotNetFunc.tlb (供 Delphi 早綁定導入用,晚綁定可選)regasm DotNetFunc.dll /codebase /tlb:DotNetFunc.tlb (寫入 HKCR,生成 TLB)gacutil -i DotNetFunc.dll (確保運行時能找到組件,/codebase 亦可但不推薦生產環境)uses Variants, ComObj, ActiveX;
procedure TForm1.Button1Click(Sender: TObject); // 解密
var SharpObject: Variant; TestValue: string;
begin
try
SharpObject := CreateOleObject('CSharpServer.SharpObject'); // ProgID: 命名空間.類名
TestValue := SharpObject.DecryptTripleDES(Edit1.Text);
Edit2.Text := TestValue;
except on E: Exception do ShowMessage(E.Message);
end;
SharpObject := Unassigned; // 釋放 COM 參考
end;
procedure TForm1.Button2Click(Sender: TObject); // 加密
var SharpObject: Variant; TestValue: string;
begin
try
SharpObject := CreateOleObject('CSharpServer.SharpObject');
TestValue := SharpObject.EncryptTripleDES(Edit2.Text);
Edit1.Text := TestValue;
except on E: Exception do ShowMessage(E.Message);
end;
SharpObject := Unassigned;
end;
initialization CoInitialize(nil); // 單元初始化:初始化 COM 庫
finalization CoUninitialize; // 單元終結:卸載 COM 庫
end.
| 環節 | 說明 |
|---|---|
CreateOleObject | 晚綁定調用,無需導入 TLB,通過 ProGID 查找 CLSID -> 實例化。返回 Variant,調用成員時動態分發 (IDispatch)。 |
Variant / Unassigned | Variant 持有 IDispatch 接口。置 Unassigned 釋放引用,觸發 COM 引用計數遞減。 |
CoInitialize/CoUninitialize | 線程級 COM 庫初始化/清理。VCL 應用主線程通常已初始化,但顯式調用更安全(特別是多線程)。 |
| 異常處理 | .NET 異常跨 COM 邊界會轉為 EOleException,E.Message 含 HRESULT 及錯誤描述。 |
| 字符串編碼 | COM BSTR 為 UTF-16,Delphi 2009+ string 即 UnicodeString,無縫對接。舊版 Delphi 需 WideString。 |
若需代碼提示與編譯期檢查,可在 Delphi IDE Component -> Import Component -> Import Type Library 選擇 DotNetFunc.tlb 生成包裝單元,然後使用生成的接口類型:var Obj: ISharpObject; Obj := CoSharpObject.Create;。
regasm /codebase 是否以管理員運行,GAC 是否安裝成功 (gacutil -l 查看)。fuslogvw 診斷綁定失敗。corflags DotNetFunc.dll /32BIT+ 強制 32 位。通過 C# COM 可見組件 + 強名稱 + GAC + Delphi 晚綁定,可在極短時間內復用 .NET 生態庫(加密、圖表、報表、機器學習等),避免重複造輪子。此模式適用於「核心邏輯用 .NET,UI/集成用 Delphi」的混合架構場景。