C++ DLL 包装器 vb.net 传递字节数组的字节数组?
C++ DLL Wrapper in vb.net Passing byte array of a byte array?
我正在调用一个函数,但我陷入了我必须传递的论点:
这就是我得到的。
函数定义:
DWORD dllexp_SetLedData(PBYTE bytArray, int arySize)
这是来自 SDK 的:
参数
姓名 |类型 |描述
字节阵列 |输入 |指向从 LED 设置转换的字节数组的指针 结构数组。
ary大小 |输入 |由 bytArray 指示的缓冲区的大小(以字节为单位)。返回值值
|描述ERROR_SUCCESS(0x0) |成功
ERROR_INVALID_OPERATION(0x10DD) |失败
VB.NET
<DllImport("GLedApi.dll", setLastError:=False, callingConvention:=CallingConvention.Cdecl)> _
Public Shared Function dllexp_SetLedData(bytArray As Byte(), arySize As Int32) As Integer
End Function
C++中LED设置的结构
typedef struct tagLedSettingData {
BYTE Reserve0;
BYTE Mode_Sel; //LED Mode
BYTE MaxBrightness; //default set to 100
BYTE MinBrightness; //defautl set to 0
DWORD dwColor; //0xWWRRGGBB, WW:0 -> WLED turn off, WW:0xFF -> WLED turn on
WORD wTime_base0; //light on time, in millisecond
WORD wTime_base1; //Interval time, in millisecond
WORD wTime_base2; //Cycle time, light on + light off <= Cycle time, this for Flash mode only
BYTE CtrlVal0;
BYTE CtrlVal1;
} LedSettingData, *LedSettingData_Ptr;
我在 vb.net 写的结构
Public Structure GLEDSETTINGS
Public Sub New(LedMod1 As ModeSelOptions, MaxB As Byte, MinB As Byte, dwColor1 As UInteger, aWtime0 As UShort, _
awtime1 As UShort, awtime2 As UShort, actrlVal0 As Byte, actrlVal1 As Byte)
Reserved0 = &H0
LedMod = LedMod1
MaxBrightness = MaxB
MinBrightness = MinB
dwColor = dwColor1
wTime0 = aWtime0
wTime1 = awtime1
wTime2 = awtime2
CtrlVal0 = actrlVal0
CtrlVal1 = actrlVal1
End Sub
Private Reserved0 As Byte
Public LedMod As ModeSelOptions
Public MaxBrightness As Byte ' max 100
Public MinBrightness As Byte
Public dwColor As UInteger ' &h0FFFFFF
Public wTime0 As UShort
Public wTime1 As UShort
Public wTime2 As UShort
Public CtrlVal0 As Byte
Public CtrlVal1 As Byte
Public Enum ModeSelOptions As Byte
Defecto = 0
Pulse
Music
ColorCycle
Statico
Flash
Transition
DigiModA
DigiModB
DigiModC
DigiModD
DigiModE
DigiModF
DigiModG
DigiModH
DigiModi
End Enum
Public Enum LedType As Integer
NA
A_LED
D_LED_TYPE1
D_LED_TYPE2
End Enum
Function ToByteArray() As Byte()
Dim size As Integer = Marshal.SizeOf(Me)
Dim arr As Byte() = New Byte(size - 1) {}
Dim ptr As IntPtr = Marshal.AllocHGlobal(size)
Marshal.StructureToPtr(Me, ptr, True)
Marshal.Copy(ptr, arr, 0, size)
Marshal.FreeHGlobal(ptr)
Return arr
End Function
End Structure
到目前为止,一切顺利,但是...我认为该函数需要一个字节数组数组。但我不知道如何在 vb.net 中做到这一点。
我唯一能做的就是:
Dim LD(iMaxDivs - 1) As GLEDSETTINGS
For I = 0 To iMaxDivs - 1
Dim L As New GLEDSETTINGS(GLEDSETTINGS.ModeSelOptions.Statico, 100, 0, &HFFFF11FFUI, 1000, 100, 0, &H0, &H0)
LD(I) = L
Next
'Dim LDParam(LDTama) As Byte
Dim LDTbrr As Byte() = LD(0).ToByteArray
Dim LDTama As Integer = Marshal.SizeOf(LD(0))
resp3 = GLed.dllexp_SetLedData(LDTbrr, LDTama)
Debug.WriteLine("SetLedData: " & resp3)
If resp3 = GLed.ERROR_INVALID_OPERATION Then
Exit Sub
End If
而且我没有收到错误,但是ERROR_INVALID_OPERATION
我转换字节数组中的结构。 在我的结构中使用ToByteArray
函数,可以正常工作,但我无法将此数组放入字节数组中,例如:不允许dim Array(10) as Byte()
。
我在 SDK 中看到了这一点C++我正在使用的 DLL 的示例中。 但我无法将其"翻译"为 vb.net。
pSettingData = new LedSettingData[iMaxDivs];
int dLen = iMaxDivs * sizeof(LedSettingData);
//ZeroMemory(pSettingData, dLen);
for (int i = 0; i < iMaxDivs; i++)
{
(pSettingData + i)->Mode_Sel = sd.Mode_Sel;
(pSettingData + i)->MaxBrightness = sd.MaxBrightness;
(pSettingData + i)->MinBrightness = sd.MinBrightness;
(pSettingData + i)->dwColor = sd.dwColor;
(pSettingData + i)->wTime_base0 = sd.wTime_base0;
(pSettingData + i)->wTime_base1 = sd.wTime_base1;
(pSettingData + i)->wTime_base2 = sd.wTime_base2;
(pSettingData + i)->CtrlVal0 = sd.CtrlVal0;
(pSettingData + i)->CtrlVal1 = sd.CtrlVal1;
}
pfSetLedData((PBYTE)pSettingData, dLen);
对此有什么看法吗?..谢谢!
你几乎是对的。C++函数需要一个GLEDSETTINGS
数组的字节数组。
要将整个GLEDSETTINGS
数组转换为字节数组,您必须创建一个新函数并调整现有代码以使用整个数组。
为此,我建议创建一个扩展方法。向项目添加新Module
:
Imports System.Runtime.CompilerServices
Public Module Extensions
<Extension()>
Public Function ToByteArray(ByVal LedSettings As GLEDSETTINGS()) As Byte()
Dim StructSize As Integer = Marshal.SizeOf(GetType(GLEDSETTINGS))
Dim Length As Integer = LedSettings.Length * StructSize 'The total amount of memory that our LedSettings array requires.
Dim Bytes As Byte() = New Byte(Length - 1) {}
Dim ptr As IntPtr = Marshal.AllocHGlobal(Length) 'Allocate a memory section for our data.
'Iterate through every GLEDSETTINGS structure and put it in our memory section.
For i = 0 To LedSettings.Length - 1
Marshal.StructureToPtr(LedSettings(i), ptr + i * StructSize, True)
Next
Marshal.Copy(ptr, Bytes, 0, Length) 'Copy the data from our memory section into our byte array.
Return Bytes
End Function
End Module
现在你可以这样称呼它:
Dim LDTbrr As Byte() = LD.ToByteArray()
resp3 = GLed.dllexp_SetLedData(LDTbrr, LDTbrr.Length)
相关文章:
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- 基于字节数组生成静态范围整数值
- 将字节数组转换为带有字节序问题的指针
- 使用 stbi_write_png,如何将 0 和 1 的矩形字节数组转换为单色 png 文件?
- 字节数组初始化会导致 DirectX 崩溃
- 使用 swig 追加到字节数组
- C++ 替换字节数组中项的顺序
- QDataStream 读取和写入的字节数比 QFile::length() 报告要多
- 如何从保存在 Java 中C++的字节数组中读取数字?
- 如何在C++(Arduino)中将浮点数组转换为字节数组
- 将字节数组转换为多维数组
- 为什么 sizeof 在 C++ 中给出不正确的字节数?
- 如何将带有空字符的字节数组馈送到 std::iostream 中?
- C++字节数组到整数
- 将字符串转换为无符号字符数组/字节数组
- 用于 progmem 的C++和头文件压缩的 Web 文件字节数组
- mmap 中的长度是字节数还是页数?
- 如果我向一个12字节的缓冲区写入的字节数少于12,会发生什么情况
- 从 UTF-8 字节数组创建字符串?
- ReadFile() 读取的字节数少于其参数中的指定值