2015-10-01 33 views
-1

我有一個DLL從那裏我只知道他的簽名就像在Delphi編寫:打電話給德爾福DLL,並通過一個C#流它

function GeResultToStream(Param1: PChar; Param2: PChar; Param3:PChar; Param4: integer; out Param5: DWord; ParamStream: IStream; Error: PChar; ErrorSize: integer):BOOL;stdcall; external 'MYDLL.dll'; 

我有一些麻煩調用從C#這個DLL方法。如果一切正常,該方法應該也傳輸ParamStream中的一些數據並返回true

我曾嘗試以下(以及其它各種DLL的方法參數的變化),但是不成功的(每次我打電話使用引用或OUT參數我是越來越錯誤此功能):

public class TestDLL 
    { 
     internal class DLLInternal 
     { 
      const string _dllLocation = "MYDLL.dll"; 

      [DllImport(_dllLocation, 
         CallingConvention = CallingConvention.StdCall, 
         CharSet = CharSet.Ansi, 
         EntryPoint = "GeResultToStream")] 
      public static extern bool GeResultToStream(string Param1, string Param2, string Param3, int Param4, char[] Param5, ref Stream ParamStream, string Error, int ErrorSize); 

     } 

     public TestDLL() 
     { 

     } 

     ~TestDLL() 
     { 

     } 

     public Stream GetStream(string Param1, string Param2, string Param3, int Param4, char[] Param5, string Error, int ErrorSize) 
     { 
      try 
      { 
       Stream stream = new MemoryStream();    
       bool x = DLLInternal.GeResultToStream(Param1, Param2, Param3, Param4, Param5, ref stream, Error, ErrorSize);  
       //here i think i might need to use somehow the Marshal class 
       return stream; 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Exception GetStream:" + ex.ToString()); 
       return null; 
      } 
     } 
    } 

我的猜測是我沒有理解如何在C#中正確使用它來轉換籤名。如果需要,我可以提供更多信息(比如我得到的錯誤,但大多數是腐敗的內存)。

+0

我想你想使用'System.Runtime.InteropServices.ComTypes.IStream' – dman2306

+0

我希望你有點困惑。像C#Streams這樣的.NET對象類型不能有意義地傳遞給Delphi,除非我們在Delphi方面介紹一些很難編寫的.NET interop代碼。你所做的事實上是瘋了。 –

+0

事實上,使用Stream對象是一個錯誤。就像David Heffernan所說的那樣,使用一個IStream接口和一個基本的包裝器就可以做到這一點。 – avi

回答

1

您的翻譯錯誤。我不知道如何將類型的參數DWORD轉換爲char[]。那應該是out uintStream不應該是ref,而且還需要是IStream接口,而不是Stream類。

的的P/Invoke應該像這樣:

[DllImport(_dllLocation, CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Ansi, EntryPoint = "GeResultToStream")] 
public static extern bool GeResultToStream(
    string Param1, 
    string Param2, 
    string Param3, 
    int Param4, 
    out uint Param5, 
    ComTypes.IStream ParamStream, 
    string Error, 
    int ErrorSize 
); 

注意,這是假定2007年的德爾福或更早版本,其中PChar映射到PAnsiChar。如果Delphi版本晚於該版本,並且PCharPWideChar,則使用CharSet.Unicode

我也假定所有的字符串參數都是用於將數據從調用者傳遞給被調用者。但可能最後的字符串參數Error並不具有這些語義。這可能是爲了傳遞錯誤文本。那麼應該用StringBuilder代替string來實施。

當然,您將需要從某處獲得IStream的實現。例如:Creating IStream object in C#。對此我很難告訴你,因爲你沒有提供任何有關如何調用函數的重要細節。你已經改變了所有參數的名字,以至於我們無法猜測語義。

隨着調試的進行,我可以看到這個問題成爲火車殘骸的一部分。我希望我被證明是錯誤的。

+0

我終於設法得到那個流信息。事實上,你的p/invoke觀察有所幫助。感謝您的幫助! – avi

+0

我還沒有提供更多的細節,因爲不幸的是,我只有一個關於我使用的dll的有限文檔,並且這些字段都是異國語言的名稱。 – avi