2014-01-28 86 views
0

我被要求爲一箇舊的delphi程序創建一個.Net dll。我試圖用COM Callable Wrapper來做到這一點,但是當它試圖加載dll時,我總是收到一個錯誤(相當普遍,像「我無法加載dll」)。這裏是技術文檔是這麼說:從delphi程序中調用COM Callable Wrapper不起作用

The DLL only needs to export one function under the name 'AUTHORIZE'. 

function Authorize(InXml: PChar): PChar; stdcall; 
(Delphi syntax. May be different in other languages.) 

這裏是我的CCW代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace ComCallableWrapper 
{ 
    [Guid("C3FD922A-FB44-47B1-9C0C-8F7FAF57098B")] 
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    public interface IAuthorizer 
    { 
     [DispId(1)] 
     string Authorize(string lnpInXml); 
    } 

    [ProgId("ComCallableWrapper.Authorizer")] 
    [ClassInterface(ClassInterfaceType.None)] 
    public class Authorizer : IAuthorizer 
    { 
     public Authorizer() 
     { 
     } 

     public string Authorize(string lnpInXml) 
     { 
      return "Approved!"; 
     } 
    } 
} 

我也運行此命令 「regasm /tlb:ComCallableWrapper.tlb ComCallableWrapper.dll /代碼庫」 上運行delphi程序的計算機。

我一直在做關於谷歌的一些研究德爾福如何調用一個DLL函數,我發現至少有2種方式:

function Authorize(lnpInXml: pchar): pchar; stdcall; external 'DLLName.dll'; 

oleObject := CreateOleObject('ComCallableWrapper.Authorizer'); 
ShowMessage(oleObject.Authorize('Approved?')); 

它看起來像COM作品有點不同。有沒有辦法改變我的CCW像第一種方式一樣工作?

問候。

+0

第一種方式看起來像是調用平面C DLL而不是COM DLL。你將無法在.NET中創建這樣的DLL。 –

+0

有50億個可能的原因實例化一個COM DLL不起作用。爲了使它變得有趣,微軟使他們都返回基本相同的錯誤代碼。你可以使用Microsoft OLE/COM Object Viewer實例化對象嗎?或與.NET代碼?在解決事情的德爾菲方面之前開始。 –

回答

0

你不需要COM。事實上,使用COM是一個錯誤,因爲Delphi程序不在尋找COM DLL。

你需要做的是從託管的C#DLL中導出一個非託管函數。這有點棘手,實際上並不支持。這些是你最有吸引力的選擇:

  1. 使用Robert Giesecke的UnmanagedExports
  2. 編寫一個消耗C#代碼的混合模式C++/CLI DLL。混合模式的C++/CLI使用__declspec(dllexport)能夠出口原生功能,.DEF文件等

如果您選擇使用UnmanagedExports,功能應該是這樣的:

[DllExport] 
public static IntPtr Authorize(string InXml) 
{ 
    // your code goes here, for now return the input value 
    return Marshal.StringToHGlobalAnsi(InXml); 
} 

實現功能有點棘手,因爲你需要返回一個Delphi PAnsiChar,這是一個C++ char*。您不能使用string作爲退貨類型,而必須使用IntPtr。但是,如何分配字符串以便調用者使用它仍然有效。上面的代碼泄漏了HGLOBAL中的字符串。

我無法明確地建議您如何解決字符串的生命週期。您編碼的界面設計得不是很好。只有掌握更多關於界面的知識才能解決這個問題。

+0

感謝您的幫助David,非常感謝。我已經嘗試過非託管出口,但我也在那裏打了一堵牆。也許你可以在這裏給我一個這樣的手:http:// stackoverflow。com/questions/21373901/c-sharp-unmanaged-exports-when-multiple-projects-involved-robert-giesecke – camendez

+0

當然我可以看一看。這個問題呢? –

+0

這是一個不同的方法,我試圖解決同樣的問題:(。 – camendez

相關問題