2011-02-04 32 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数组本身的地址。