2017-08-24 166 views
0

我必須使用C#訪問動態庫。 它使用COM庫時效果很好,但是當我嘗試使用動態庫時,它會導致錯誤。C# - 從動態庫DLL調用函數

1日問題

起初,我不喜歡這樣我的代碼:

[DllImport("mydll.dll")] 
public static extern int toGetInfo(uint id, char[] strVolume, char[] strInfo); 
// strVolume and strInfo is parameter that return value with [out] 

public static void Main() 
{ 
char[] test1,test2; 
toGetInfo(0,test1,test2); 
} 

但它無法與錯誤使用未分配的局部變量的測試1和測試2編譯。 後來我加入了這個編輯我的代碼:

[DllImport("mydll.dll")] 
public static extern int toGetInfo(uint id, out char[] strVolume, out char[] strInfo); 
// strVolume and strInfo is parameter that return [out] 

public static void Main() 
{ 
char[] test1,test2; 
toGetInfo(0, out test1, out test2); 
} 

它能夠編譯但返回空值TEST1和TEST2。

第二個問題

[DllImport("mydll.dll")] 
public static extern int toOpen(uint id, char* name); 

public static void Main() 
{ 
char name; 
toOpen(0, name); 
} 

當編譯它給錯誤

任何想法如何做「指針和固定大小的緩衝區只可以在不安全的上下文中使用」?

+0

一個字符是在C#中的兩個字節,並在C它可能是一個。在c#中使用一個字節[]。在c中,字符數組以'\ 0'結尾,因此最好使用IntPtr Marshal.StringToHGlobalAnsi(string),它自動完成所有工作。所以將char []聲明爲IntPtr。 – jdweng

+0

更改爲intPtr後,它提供了一些東西。等待我會更新 – njz

回答

1

嘗試以下操作:

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


namespace ConsoleApplication74 
{ 
    class Program 
    { 
     [DllImport("mydll.dll")] 
     public static extern int toGetInfo(uint id, IntPtr strVolume, IntPtr strInfo); 

     [DllImport("mydll.dll")] 
     public static extern int toOpen(uint id, IntPtr name); 

     const int STRING_LENGTH = 256; 
     static void Main(string[] args) 
     { 

      IntPtr strVolumePtr = Marshal.AllocHGlobal(STRING_LENGTH); 
      IntPtr strInfoPtr = Marshal.AllocHGlobal(STRING_LENGTH); 

      uint id = 123; 

      int status1 = toGetInfo(id, strVolumePtr, strInfoPtr); 

      string strVolume = Marshal.PtrToStringAnsi(strVolumePtr); 
      string strInfo = Marshal.PtrToStringAnsi(strInfoPtr); 

      string name = "John"; 
      IntPtr openNamePtr = Marshal.StringToHGlobalAnsi(name); 
      int status2 = toOpen(id, openNamePtr); 

      Marshal.FreeHGlobal(strVolumePtr); 
      Marshal.FreeHGlobal(strInfoPtr); 
      Marshal.FreeHGlobal(openNamePtr); 

     } 

    } 

} 
+0

謝謝你的作品! – njz

+0

嗨想問一下,如果我不確定STRING_LENGTH,是否有一招會遇到這種情況?謝謝 – njz

+0

它是否也適用於dword和byte? – njz