2012-07-12 22 views
1

我有Delphi編寫的非託管的DLL文件,其中包含如下定義的函數:編組PDouble(C# - >德爾福)

function F(tgran: integer; inputs: PDouble; goutp, outputs, toutp: PDouble): integer; stdcall; external 'mydll.dll'; 

我已經寫在C#中的適配器應該幫助我消耗它。

[UnmanagedFunctionPointer(APIAdapter.Convention)] 
public delegate int FDelegate(int tgran, IntPtr inputs, IntPtr goutp, IntPtr outputs, IntPtr toutp); 

public class APIAdapter : IDisposable 
    { 
     public const string DllName = "mydll.dll"; 
     public const CallingConvention Convention = CallingConvention.StdCall; 
     public FDelegate F; 
     [DllImport("kernel32")] 
     private static extern IntPtr LoadLibrary(string lpLibFileName); 

     [DllImport("kernel32")] 
     private static extern bool FreeLibrary(IntPtr hModule); 

     [DllImport("kernel32.dll")] 
     private static extern IntPtr GetProcAddress(IntPtr hModule, String procname); 

     private IntPtr _dllHandle; 
     public APIAdapter() 
     { 
      _dllHandle = LoadLibrary(DllName); 

      F = (FDelegate)GetFunction<CalcCavSpDelegate>("F");   
     } 

     private Delegate GetFunction<T>(string procName)    
     { 
      IntPtr procAddress = GetProcAddress(_dllHandle, procName); 
      return Marshal.GetDelegateForFunctionPointer(procAddress, typeof(T)); 
     } 

     ~APIAdapter() 
     { 
      Dispose(false); 
     } 

     public void Dispose() 
     { 
      Dispose(true); 
      GC.SuppressFinalize(this); 
     } 

     private void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
      } 

      while (FreeLibrary(_dllHandle)) 
      { 
      } 
     } 
    } 

的使用是非常簡單的:

using(var api = new APIAdapter()) 
{ 
    // Call API functions 
} 

的問題是DLL文件中會發生,一個AccessViolationException。

我試過把012變量作爲double[], double* (unsafe code), IntPtr。不管我選擇什麼方法,都是一樣的故事。我試圖大幅增加傳入的數組的大小,以排除數組索引中的錯誤 - AccessViolation異常。

將一個PDouble傳遞給一個非託管的Delphi DLL文件的正確方法是什麼?

+0

由於我們不知道數組有多大以及誰負責分配它們,所以不可能爲此提供代碼。另外,我敦促你用'DllImport'重寫代碼,以便問題可以集中在真正的問題上。 – 2012-07-12 12:19:36

+0

同樣令人驚訝的是,您包含了所有樣板鏈接代碼,但省略了實際調用本地DLL的代碼! – 2012-07-12 12:33:57

+0

我將很快更新上面的帖子(tm) – Maciek 2012-07-12 15:03:30

回答

1

我認爲你可以通過簡單地使用DllImport屬性來消除所有的LoadLibraryGetProcAddressFreeLibrary的複雜性。雖然,我可以說我不知道​​你爲什麼選擇這種方式的具體原因。

無論如何,您可以簡單地在您的聲明中包含ref double doubleArg以傳遞PDouble。這裏不需要IntPtr

+1

這對標量來說很好,但是這些都是數組。 – 2012-07-12 12:19:47

+1

是的,確切地說,我正在傳遞數組:/ - 看來問題仍然存在於PByte中,我也沒有在這裏列出函數。 – Maciek 2012-07-12 15:01:31

+0

我以爲他試圖將指針傳遞給double:)...將看看我是否可以弄清楚如何爲數組做這個操作 – 2012-07-13 05:22:45