Please forgive me if this is a rather simple question / solution, as I am a systems level programmer by trade (spend all my time in Asm and C, with about zero time spent in VB/VB.Net) who has been asked to interface to some of our system level components via VB.Net and a DLL.
The problem that I am having is that when I try to make a call into our dll (for this test the dll function does nothing but memset the address passed in to the function: See Below function code snippet) using my VB.Net defined structures I receive memory error in VB.Net; however, when I switch to using a Byte Array all works well.
The params that I need to use are structure blocks and not byte arrays as I do not wish to copy the data out of a byte buffer and place them into my structure members.
At this point, I can not begin to tell you how many hours I have wasted on this
(along with how many different ways that I have tried)!
Here is my class information (This has the subroutine that uses the Byte Array and thusly works) -- to help clear up the mud from the projects specific naming conventions and the such I have renamed all vars and functions to generic terms:
Thank you so much for any help that you could provide me on this.
Now if I make the following changes, in-order-to use my structures rather than using the Byte Array I will get an error message:
Error Message:
and here is the code snippet for the dll:
The problem that I am having is that when I try to make a call into our dll (for this test the dll function does nothing but memset the address passed in to the function: See Below function code snippet) using my VB.Net defined structures I receive memory error in VB.Net; however, when I switch to using a Byte Array all works well.
The params that I need to use are structure blocks and not byte arrays as I do not wish to copy the data out of a byte buffer and place them into my structure members.
At this point, I can not begin to tell you how many hours I have wasted on this
Here is my class information (This has the subroutine that uses the Byte Array and thusly works) -- to help clear up the mud from the projects specific naming conventions and the such I have renamed all vars and functions to generic terms:
Thank you so much for any help that you could provide me on this.
VB.NET:
Imports System.Runtime.InteropServices
'
' ***** Structure Definitions *****
'
Public Structure Struct1
'
' Public Members First
'
Public Var1 As Byte
Public Var2 As Byte
Public Var3 As Byte
Public Var4() As Byte
Public Var5 As Byte
Public Var6() As Byte
Public Var7 As Byte
Public Var8 As Byte
Public Var9 As Byte
Public Var10() As Byte
End Structure
Public Structure Struct2
'
' Public Members First
'
Public Var1 As Long
Public Var2 As Long
Public Var3 As Long
Public Var4 As Integer
Public Var5 As Byte
Public Var6 As Byte
Public S1 As Struct1
Public Var7() As Byte
End Structure
Public Structure Struct3
'
' Public Members First
'
Public Var1 As Byte
Public Var2 As Byte
Public Var3 As Byte
Public Var4 As Byte
Public Var5 As Byte
Public Var6() As Byte
Public Var7 As Byte
Public Var8() As Byte
Public Var9() As Byte
Public Var10() As Byte
Public Var11() As Byte
Public Var12() As Byte
Public Var13() As Byte
Public Var14() As Byte
Public Var15() As Byte
Public Var16() As Byte
Public Var17() As Byte
Public Var18() As Byte
Public Var19() As Byte
Public Var20() As Byte
End Structure
Public Class MainClass
'
' Private Structures
'
Private _S2 As Struct2
Private _S3 As Struct3
'
' Our Constructor
'
Public Sub New()
ReDim _S2.Reserved(1)
ReDim _S2.S1.Var4(3)
ReDim _S2.S1.Var6(2)
ReDim _S2.S1.Var10(3)
ReDim _S3.Var6(1)
ReDim _S3.Var8(7)
ReDim _S3.Var9(15)
ReDim _S3.Var10(3)
ReDim _S3.Var11(4)
ReDim _S3.Var12(3)
ReDim _S3.Var13(7)
ReDim _S3.Var14(2)
ReDim _S3.Var15(31)
ReDim _S3.Var16(7)
ReDim _S3.Var17(7)
ReDim _S3.Var18(7)
ReDim _S3.Var19(3)
ReDim _S3.Var20(19)
End Sub
Public Sub CallFillStructures(ByRef ReturnResults As Long)
Dim Index As Integer
Dim ReturnCode As Long
Dim Test1() As Byte
Dim Test2() As Byte
ReDim Test1(40)
ReDim Test2(136)
Index = 0
ReturnCode = FillStructures(Index, Test1, Test2)
End Sub
' ***** Imported DLL functions *****
'
<DllImport("MyTest.dll", CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function FillStructures(ByVal Val1 As Integer, ByVal Val2() As Byte, ByVal Val3() As Byte) As Long
End Function
End Class
Now if I make the following changes, in-order-to use my structures rather than using the Byte Array I will get an error message:
VB.NET:
'
' This fails with an Error Message (See Below)
'
Public Sub CallFillStructures(ByRef ReturnResults As Long)
Dim Index As Integer
Dim ReturnCode As Long
Index = 0
ReturnCode = FillStructures(Index, _S2, _S3)
End Sub
' ***** Imported DLL functions *****
'
<DllImport("MyTest.dll", CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function FillStructures(ByVal Val1 As Integer, ByRef Val2 As _S2, ByRef Val3 As _S3) As Long
End Function
Error Message:
An unhandled exception of type 'System.AccessViolationException' occurred in FirmwareManagementSystem.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
and here is the code snippet for the dll:
VB.NET:
[B][COLOR="Blue"]MyTest.dll:[/COLOR][/B]
ULONG APIENTRY FillStructures (
UCHAR Index,
PStruct1 pStruct1,
PStruct2 pStruct2)
{
// Zero the LCStatus structure passed, if not correctly allocated will cause problems.
memset ((UCHAR *)pStruct1, 0x1, sizeof(Struct1));
memset ((UCHAR *)pStruct2, 0x2, sizeof(Struct2));
//
// To simplify the debugging process I have removed everything from this function except the memset command
//
return(0x12345678);
}