我在调用C DLL中的函数时遇到麻烦(不知道是C还是C ++)
基本上,我正在尝试为Gigabyte RGB Fusion API的SDK DLL创建一个包装器。
我使用Visual Studio 2013在VB.NET中工作(如果你在C#中回答也很好)
使用DLLImport声明函数
代表。这个功能很好。
C ++
int dllexp_GetMaxDivision(void)
VB.NET
<DllImport("GLedApi.dll", SetLastError:=False, callingConvention:=CallingConvention.Cdecl)> _
Public Shared Function dllexp_GetMaxDivision() As UInt32
EndFunction
调用dllexp_GetMaxDivision
就像一个魅力。当我传递参数时,麻烦就开始了:
DWORD dllexp_GetLedLayout(PBYTE bytArray, int arySize)
参数
名称/类型/说明
bytArray / Output /指向接收主板上LED布局的缓冲区的指针。数组中元素的值如下: 价值意义
0(NA)无工具LED
1(A_LED)模拟LED
2(D_LED_TYPE1)数字LED类型1
3(D_LED_TYPE2)数字LED类型2
arySize / Input / Size,由bytArray指示的缓冲区的字节。该值必须是
dllexp_GetMaxDivision
返回值。
DWORD dllexp_SetLedData(PBYTE bytArray, int arySize)
参数
名称/类型/说明
bytArray / Input /指向从LEDSETTING转换的字节数组的指针 结构数组。
由byAAray指示的缓冲区的arySize / Input / Size(以字节为单位)。
typedef struct _LEDSETTING {
BYTE Reserve0;
BYTE LedMode;
BYTE MaxBrightness;
BYTE MinBrightness;
DWORD dwColor;
WORD wTime0;
WORD wTime1;
WORD wTime2;
BYTE CtrlVal0;
BYTE CtrlVal1;
} LEDSETTING, *PLEDSETTING
这是我尝试的。我还没有使用dllexp_SetLedData
进行测试,因此我将重点关注dllexp_GetLedLayout
<DllImport("GLedApi.dll", setLastError:=False, CallingConvention:=CallingConvention.Cdecl)> _
Public Shared Function dllexp_GetLedLayout(ByRef bytArray As IntPtr, arySize As Int32) As UInt32
End Function
尝试使用字节数组,但没有工作。而这:
Dim Param(iMaxDivs - 1) As Byte
For A As Integer = 0 To iMaxDivs - 1
Param(A) = CByte(0)
Next
Dim Tama As Integer = Marshal.SizeOf(Param(0)) * Param.Length
Dim buffer As IntPtr = Marshal.AllocHGlobal(Tama)
Marshal.Copy(Param, 0, buffer, Param.Length)
resp2 = GLed.dllexp_GetLedLayout(buffer, Param.Length)
Marshal.Copy(buffer, Param, 0, Param.Length) '<===== AccessViolationException
Marshal.FreeHGlobal(buffer)
将缓冲区检索到数组的代码行引发异常:
&#39; System.AccessViolationException&#39; en mscorlib.dll尝试阅读或 写保护的内存。这通常表明其他记忆 是腐败的。
在其他一些测试中,我有PinvokeImbalance
种...,我猜这是一种类型不匹配。
奇怪的是,有时,代码不会抛出异常并继续,但返回零填充数组。即使缓冲区包含数据。
我也尝试使用AllocCoTaskMem
但过程崩溃......,
有人可以用正确的方式指出我吗?
谢谢!