VB.NET错误"类型的值' Ushort'无法转换为' Ushort()'"从本机C ++ DLL读取二维字节数组

时间:2017-09-27 18:09:35

标签: c++ .net vb.net dll

我收到VB错误:"类型值' Ushort'无法转换为' Ushort()'"。

我有一个VB.NET Windows应用程序,它调用本机(C ++)DLL中的函数,从DLL中的页面数组中读取特定的256字节页面。

DLL函数中的VISUAL-C ++声明,函数....

extern "C" BASICDLL_API int __stdcall My_Read_High_Speed_Data(unsigned char ptr, unsigned short *buf)
{
    return BDLL_ReadBlock(0x00300000 + ptr, (unsigned char *)buf);
}

VB.NET声明DLL中的函数................

<DllImport("MyDll.dll", CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Ansi)>
Public Function My_Read_Parameters(ByVal board As Byte, ByVal params As UShort()) As Int32
End Function

声明VB.NET缓冲区,用于保存64个256字节的页面,来自DLL ...............

Dim input_page_buffer( 64, 256 ) As UInt16

VB.NET函数从DLL中读取页面...................

function poll()                         
    dim page_index = 1
    dim success = My_Read_High_Speed_Data( page_index, input_page_buffer(1, 1)  )
end function

2 个答案:

答案 0 :(得分:0)

dll导入功能

..., ByVal params As UShort()

要求UShort()作为第二个参数,而c ++有

..., unsigned short *buf)

将dll导入更改为UShort

答案 1 :(得分:0)

正确阅读问题后(:))我想我明白了你要做的事情...... C ++函数期待它的buf字节数组参数,然后由BDLL_ReadBlock()函数填充256个字节。

为什么你已将参数声明为unsigned short*而不是unsigned byte*我不明白,因为BDLL_ReadBlock()显然需要后者。

无论如何,要解决此问题,您必须从二维数组切换到jagged array。这是因为他们做了不同的事情:

  • 在二维数组中,您将所有项目都放在网格中,非常类似于固定坐标系:
    Array(3, 3):
        0  1  2  3
     0  A  B  C  D
     1  E  F  G  H
     2  I  J  K  L
     3  M  N  O  P
  • 但是,锯齿状阵列是一个 数组 ,这意味着你有一组列和行,其中每列的列数不一定必须相同:

    Array(3)(3):
         0   1   2   3
     0  {A,  B,  C,  D}
     1  {E,  F,  G,  H}
     2  {I,  J,  K,  L}
     3  {M,  N,  O,  P}
    
    Array(3)(x):
         0   1   2   3   4
     0  {A,  B}
     1  {C,  D,  E,  F,  G}
     2  {H,  I,  J}
     3  {K}
    

访问项目时的区别在于,在2D数组中,您一次只能获得 ONE item

Array(1, 3) = H

...而在锯齿状数组中,您不一定要访问只有一个项,但您也可以引用整行:

'Single item.
Array(1)(3) = H

'Entire row.
Array(1) = {E, F, G, H}

继续......

由于BDLL_ReadBlock()似乎期望一个字节数组,你应该改变你的C ++方法以获取一个(如果你有权访问源,那就是):

extern "C" BASICDLL_API int __stdcall My_Read_High_Speed_Data(unsigned char ptr, unsigned char *buf)
{
    return BDLL_ReadBlock(0x00300000 + ptr, buf);
}

然后更改VB.NET声明:

<DllImport("MyDll.dll", CallingConvention:=CallingConvention.StdCall)>
Public Function My_Read_High_Speed_Data(ByVal ptr As Byte, ByVal buf As Byte()) As Integer
End Function

最后,将VB.NET数组更改为锯齿状数组,而不是2D数组:

Dim input_page_buffer(64 - 1)() As Byte
'In VB.NET you specify the upper bound INDEX of an array, not how many items it should contain.
'Thus "Dim Array(64)" creates an array of 65 items (since indexes are zero-based), and "Dim Array(64 - 1)" or "Dim Array(63)" creates an array of 64 items.

唯一的缺点是你必须分别初始化锯齿状数组的内部数组:

For x = 0 To input_page_buffer.Length - 1
    input_page_buffer(x) = New Byte(256 - 1) {}
Next

最后,调用函数:

Function poll()
    Dim page_index As Byte = 1

    'input_page_buffer(0) gives you the first 256-byte array.
    Dim success As Integer = My_Read_High_Speed_Data(page_index, input_page_buffer(0))

    ...
End Function

如果您无法更改C ++代码的来源,那么只需用Byte(...)替换我代码中的每个UShort(...),您就应该好了!