poupou
asked on
Application Error crashes the program
Hi,
I still have my Application Error when calling the Win32 ReadFile function. Below is my code. The WriteFile works well, and the file written to is correct.
So, whats wrong.
Public Declare Function ReadFile Lib "kernel32" Alias "ReadFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long
Private Type Record ' Define user-defined type.
ID As Integer
LD As Long
Name As String * 20
Surname As String
End Type
Sub ReadBinary()
Dim handle, res, bytesRead, length As Long
Dim nul As Variant
Dim sa As SECURITY_ATTRIBUTES
Dim ov As OVERLAPPED
Dim txt As String
Dim buffer As String * 10
Dim MyRecord As Record ' Declare variable.
sa.nLength = 0
sa.lpSecurityDescriptor = 0
sa.bInheritHandle = 0
ov.Internal = 0
ov.InternalHigh = 0
ov.offset = 0
ov.OffsetHigh = 0
ov.hEvent = 0
handle = CreateFile("c:\bas.bin", _
GENERIC_READ Or GENERIC_WRITE, _
0, _
sa, _
OPEN_EXISTING, _
0, _
0)
If handle = INVALID_HANDLE_VALUE Then
Win32Error "CreateFile", GetLastError
Else
length = Len(buffer)
res = ReadFile(handle, buffer, length, bytesRead, vbNull)
' below the old code, which also does not work
' length = Len(MyRecord)
' res = ReadFile(handle, MyRecord, length, bytesRead, vbNull)
If res = 0 Then
Win32Error "ReadFile", GetLastError
res = CloseHandle(handle)
If res = 0 Then
Win32Error "CloseHandle", GetLastError
End If
End If
txt = "MyRecord: Id=" & MyRecord.ID & " LD=" & MyRecord.LD & " name=" & MyRecord.Name & " Surname=" & MyRecord.Surname
MsgBox txt, vbInformation, "ReadBinary"
End Sub
I still have my Application Error when calling the Win32 ReadFile function. Below is my code. The WriteFile works well, and the file written to is correct.
So, whats wrong.
Public Declare Function ReadFile Lib "kernel32" Alias "ReadFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long
Private Type Record ' Define user-defined type.
ID As Integer
LD As Long
Name As String * 20
Surname As String
End Type
Sub ReadBinary()
Dim handle, res, bytesRead, length As Long
Dim nul As Variant
Dim sa As SECURITY_ATTRIBUTES
Dim ov As OVERLAPPED
Dim txt As String
Dim buffer As String * 10
Dim MyRecord As Record ' Declare variable.
sa.nLength = 0
sa.lpSecurityDescriptor = 0
sa.bInheritHandle = 0
ov.Internal = 0
ov.InternalHigh = 0
ov.offset = 0
ov.OffsetHigh = 0
ov.hEvent = 0
handle = CreateFile("c:\bas.bin", _
GENERIC_READ Or GENERIC_WRITE, _
0, _
sa, _
OPEN_EXISTING, _
0, _
0)
If handle = INVALID_HANDLE_VALUE Then
Win32Error "CreateFile", GetLastError
Else
length = Len(buffer)
res = ReadFile(handle, buffer, length, bytesRead, vbNull)
' below the old code, which also does not work
' length = Len(MyRecord)
' res = ReadFile(handle, MyRecord, length, bytesRead, vbNull)
If res = 0 Then
Win32Error "ReadFile", GetLastError
res = CloseHandle(handle)
If res = 0 Then
Win32Error "CloseHandle", GetLastError
End If
End If
txt = "MyRecord: Id=" & MyRecord.ID & " LD=" & MyRecord.LD & " name=" & MyRecord.Name & " Surname=" & MyRecord.Surname
MsgBox txt, vbInformation, "ReadBinary"
End Sub
Initially I think that it may be because bytesRead is not declared anywhere which would make it of type variant. Try using Option Explicit at the top of your module.
Hello,
I think you better chang your function call to ReadFile like this
res = ReadFile(handle, BYVAL buffer, length, bytesRead, CLng(0))
You must add the Byval keyword before passing the 'String' buffer to the ReadFile API function !
Have a look at this link, it's all explained and there is also a 'Visual Basic Specific' section on the page !!
http://www.vbapi.com/ref/r/readfile.html
Hope this will work.
Patrick.
I think you better chang your function call to ReadFile like this
res = ReadFile(handle, BYVAL buffer, length, bytesRead, CLng(0))
You must add the Byval keyword before passing the 'String' buffer to the ReadFile API function !
Have a look at this link, it's all explained and there is also a 'Visual Basic Specific' section on the page !!
http://www.vbapi.com/ref/r/readfile.html
Hope this will work.
Patrick.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oh yeah, I didn't see that. Definitely listen to PatrickVD, I'm sure that's it (although you should also check bytesRead but I'd give the points to PatrickVD).
Nice code.. but for the life of me I can't understand why you are using a Readfile API rather than just a simple VB Open Binary - Get - Put routine. What am I missing here?
A few notes that may help:
1. The way you declare your Long variables is incorrect and will result in all but one of them being defined as Variants. In VB, you can't define a list of variables as a certain data type like you can in C++. Define each one individually. ("Dim handle As Long", "Dim res As Long", etc.)
2. Change your ReadFile API declaration's lpOverlapped argument to "ByVal lpOverlapped As Long" instead of "lpOverlapped As OVERLAPPED". Pass a value of zero to the function for this argument instead of VbNull (which has a value of 1).
Finally, like wsh2 I have to wonder why you're going through the trouble of using the ReadFile function instead of using regular Binary file access functions.
Good luck,
Rob
<Smiling, batting eyelashes and speaking in sultry southern voice>.. "C'mon poupou,".. <wink> <wink>.. "Enquiring Expert minds wanna know!".. <smile>.
ASKER
thanks PatrickVD for your help,
just adding the ByVal before the buffer parameter stops my pg to crash.
comment for rob and wsh2:
using the standard put and get is effectively a better way to access binary file.
But I just don't like my applications to crash without finding the problem.
just adding the ByVal before the buffer parameter stops my pg to crash.
comment for rob and wsh2:
using the standard put and get is effectively a better way to access binary file.
But I just don't like my applications to crash without finding the problem.