2011-01-05 49 views
0

我想從c dll導入一個函數到C#中。 C函數看起來像這樣正確的C#dll導入功能

unsigned short write_buffer(unsigned short device_number, unsigned short word_count, unsigned long buffer_link, unsigned short* buffer) 

我在C#進口嘗試看起來像這樣

[DllImport("sslib32.dll", CharSet = CharSet.Ansi, SetLastError = true)] 
private static extern ushort write_buffer(ushort deviceNumber, ushort wordCount, UInt32 bufferLink, IntPtr buffer) 

在C#我有我想傳遞給這個函數消息的字典。字典看起來像這樣:

Dictionary<string, List<ushort>> msgs 

我有點困惑如何使一個適當的調用傳遞消息作爲緩衝區。 deviceNumber爲2,是的wordCount 32和buffLink爲0,所以我知道調用應該是這個樣子

write_buffer(2,32,0, msgs[key]); 

顯然,我得到了IntPtr的無效參數。打這個電話的正確方法是什麼?

回答

2

什麼緩衝區應該包含和其數據流向哪個方向是相當不清楚的。你的字典表明它應該是一個數組。只需聲明如下:

private static extern ushort write_buffer(.., ushort[] buffer); 

並在調用中使用msgs [key] .ToArray()。

在write_buffer()調用中使用常量並不是一個可能的場景,但應該有msgs [key] .Count在那裏。

+0

謝謝,對不起,問題有點不清楚,但你提供的答案似乎工作正常。 – poco 2011-01-05 18:55:11

1

您可以使用標記爲here的P/Invoke Interop Assistant工具生成P/Invoke簽名。

在MSDN 雜誌,張翼和小英郭 的2008年1月發行對管理之間 非託管代碼編組發表了CLR內而外列 。在該列中,他們引入了P/Invoke Interop Assistant,一個自動GUI和 命令行實用程序,用於在託管和非託管 簽名(雙向)之間轉換 。這個 轉換當然不僅僅限於Windows簽名的 ;給 工具一個你自己的C頭文件 的片段,它會盡職盡責地把它們轉換成漂亮的C# [DllImport]的。

+0

它在這裏沒有幫助。如果C聲明有SAL註釋,該工具只能做一個體面的工作。在這裏沒有,沒辦法告訴這是否是一個數組。 – 2011-01-05 17:57:39

0

如果你不介意將代碼標記不安全的,你可以簡單地做:

fixed(ushort* pData = msgs[key]) 
{ 
    write_buffer(2,32,0, pData); 
} 

,並宣佈你的DllImport採取USHORT *作爲最後一個參數。

另一種方法是使用Marshal.StructureToPtr將數組編碼到固定存儲器中。這要求您首先使用AllocHGlobal分配內存,然後使用FreeHGlobal釋放內存。