2011-02-04 72 views
5

我們正在構建一個針對x32的Win7 x64上的c#,.net 4.0應用程序。PInvoke,指針和陣列副本

我們在我們的應用程序中使用第三方庫。我們知道這個庫是用C++編寫的。但是,爲了讓c#開發人員使用這個庫,他們使用P/Invoke來封裝它,所以我們稱之爲API函數。

一個API調用的如下:

ReadFromDevice(int deviceAddress, int numBytes, Byte[] data); 

該功能從外部裝置讀出的數據的的numBytes,並將其放置在數據[]。正如你所看到的,它期望看到一個C#Byte數組作爲第三個參數。現在,我們的問題是,我們想要將數據讀取到預先聲明的數組中的任意位置。例如:

Byte[] myData = new Byte[1024*1024*16]; 
ReadFromDevice(0x100, 20000, &myData[350]) // Obviously not possible in C# 

如果我們使用C/C++,這將是微不足道的。考慮到底層API是用C++編寫的,我覺得我們應該可以在C#中完成這個工作,但是,我無法弄清楚如何在C#中執行此操作。也許我們可以不通過提供的P/Invoke接口調用底層庫並編寫自定義接口?

任何想法,將不勝感激。

Regards,

回答

3

雖然這裏的其他答案很接近,但都不完整。

首先,您只需聲明自己的p/invoke聲明。這是p/invoke的甜蜜之處;從來沒有一種方法可以做到這一點。

[DllImport("whatever.dll")] 
unsafe extern static void ReadFromDevice(int deviceAddress, int numBytes, byte* data); 

現在你可以用

unsafe static void ReadFromDevice(int deviceAddress, byte[] data, int offset, int numBytes) 
{ 
    fixed (byte* p = data) 
    { 
     ReadFromDevice(deviceAddress, numBytes, p + offset); 
    } 
} 
3

你可以使用指針,但需要建立在檢測到不安全模式下。

Byte[] myData = new Byte[1024*1024*16]; 
fixed(Byte * pB = &myData[350]) 
{ 
    ReadFromDevice(0x100, 20000,pB ) 
} 

但首先您需要將導出的方法簽名更改爲。

ReadFromDevice(int deviceAddress, int numBytes, Byte * data); 
+0

稱之爲有沒有從'字節*`轉換爲`的byte []`,這段代碼甚至不會編譯。如果他控制了C#源代碼,那將是一回事,但這聽起來不像他原來的問題。 – 2011-02-04 08:54:59

+0

這就是說,在再次閱讀問題時,它聽起來像OP也可以訪問C++庫,因此您應該簡單地建議他添加自己的DllImport並將簽名更改爲接受「byte *」而不是`byte []`,那麼這將工作。刪除downvote。 – 2011-02-04 09:03:03

+0

「 我們正在構建一個應用程序在c#,.net 4.0,在Win7 x64上,目標是x32 我們在我們的應用程序中使用第三方庫我們知道這個庫是用C++編寫的,但是爲了讓c#開發人員使用這個庫,他們使用P/Invoke來封裝它,所以我們稱之爲API函數。「 所以他們控制了C#併爲C++庫編寫了一個包裝器! – N4rk0 2011-02-06 22:35:15

0

一樣簡單的:

ReadFromDevice(int deviceAddress, int numBytes, ref byte data);

...


Byte[] myData = new Byte[1024*1024*16]; 
ReadFromDevice(0x100, 20000, ref myData[350]) // Obviously possible in C# 
0

解決這個問題似乎有點明顯。

雖然這是真的,但您可以簡單地創建自己的包裝類和DllImport並編寫自己的包裝類,解決方案更容易。

ReadFromDevice(int deviceAddress, int numBytes, Byte[] data); 

在您的發佈數據的上下文中是輸出參數。所以解決方法是發送一個適當大小的空Byte數組,然後將已填充的數組放入您現有的數組中。

您所要做的就是確定返回的數組的大小,然後再手動填充和替換。

我只是簡單地告訴你,使用現有數組的想法可能只適用於在數組內發送specfic元素的地址(這可能是certianly),但限於C++庫實際上預計哪些可能只是Byte數組本身的地址。