problem calling API in VBA

M

Mark

I have an sdk that I need to use (secbank.dll to access the Biometrika
Fx3000 fingerprint scanner)

I have had to covert from the 'C' header file sample into a VB DLL
function, but I've obviously go it wrong because Access keeps on
crashing.

I think the problem is with 'fileName' parameter - any obvious mistake?
(the maximum file length is 16 characters)


C ORIGINAL:

SECBANKDLL_API UINT SB_CALLMODE SecBank_Create (Device Disp, char
*fileName, DWORD *IDSecBank, BYTE *Pin, DWORD lenPin); //Creates a new
SecBank on the scanner RAM


VB:

Public Declare Function SecBank_Create Lib "SecBank.dll" (ByVal Device
As Long, ByVal afileName As Byte, ByVal aIDSecBank As Long, ByRef aPin
As Byte, ByVal lenPin As Long) As Integer 'Creates a new
SecBank on the scanner RAM


Code:
Dim RetV As Long
Dim SB_ID As Long
Dim PinArr() As Byte
Dim FileName() As Byte
Const IDDevFlashScanner As Long = 1
Const Pin As String = "12345678901234567890123456789012"
Const FName As String = "FileName00123456"
PinArr() = StrConv(Pin, vbFromUnicode)
FileName() = StrConv(FName, vbFromUnicode)
RetV = SecBank_Create(IDDevFlashScanner, FileName(0), SB_ID,
PinArr(0), 32)
If RetV <> 0 Then Call FPErrMsg(RetV)
 
T

Tom Wickerath

Hi Mark,

I certainly don't know the answer for sure, but I will offer some guesses
for you to consider...

The declaration (Public Declare Function SecBank_Create) includes ByRef aPin
As Byte. However, in your call to the function you are passing an array of
type byte, not a byte. Perhaps (?) this line of code:

PinArr() = StrConv(Pin, vbFromUnicode)

should be changed to:

PinArr = StrConv(Pin, vbFromUnicode)


Also, you have declared RetV As Long, yet your function is set to return an
Integer. I don't know if this could cause a problem or not.


Tom Wickerath
Microsoft Access MVP
http://www.accessmvp.com/TWickerath/
http://www.access.qbuilt.com/html/expert_contributors.html
__________________________________________
 
M

Mark

The declaration (Public Declare Function SecBank_Create) includes ByRef
aPin As Byte. However, in your call to the function you are passing an
array of type byte, not a byte. Perhaps (?) this line of code:

PinArr() = StrConv(Pin, vbFromUnicode)

should be changed to:

PinArr = StrConv(Pin, vbFromUnicode)

Thanks Tom for helping, let me elaborate.

A byte variable can only carry 1 byte. So if the pin (hopefully)
contains a few characters then it must be held in an array. The clue
that this is correct is the fact that there is also a lenPin parameter
to determine the length of the array. This is typical of C, which cannot
determine lengths of arrays, and always requires a second parameter for
this purpose.

I think the char *fileName is where the problem lies. I am assuming
that 'byte' data type is the vb equivalent of C's 'char' (so write
litwin & getz in the Access Developer Handbook in their chapter on DLLs)
So, again, a filename with multiple characters, would have to be passed
as an array. But this seems wrong because a second parameter should be
provided (i.e. lenPassword) to determine the array length - and it
isn't.

I have tried changing afileName in the declared function to ByVal
afileName As String and passing a string variable - but the function
returns an input error - so this must be wrong. (The error for the byte
type is a GP crash.)

To summarise:

how do you present char *fileName in vb:
If this is an byte array - why isn't there a parameter for the length?
If a string variable - why doesn't the dll like it?

I unfortunately don't know about C - I need help from someone who does.
Also, you have declared RetV As Long, yet your function is set to
return an Integer. I don't know if this could cause a problem or not.

Didn't help.
 
T

Tom Wickerath

Hi Mark,
A byte variable can only carry 1 byte.

I agree.

I am assuming that 'byte' data type is the vb equivalent of C's 'char' (so write
litwin & getz in the Access Developer Handbook in their chapter on DLLs)

I don't know that this is true....what page do you see this mentioned on?
Are you basing this on Table 16.1 (page 1033) of the Access 2002 Desktop
Developer's Handbook? The Access Help file shows the following:

"Byte variables are stored as single, unsigned, 8-bit (1-byte) numbers
ranging in value from 0–255."

Assuming you have the same book that I do, did you read the information on
page 1023 "Passing an Array"? This includes the following quote:

"You can pass individual elements of an array just as you would use any
other variable. Sometimes, though, you'll want to pass an entire array to a
DLL. You may do this--but only for numeric arrays, not for strings or
user-defined arrays, unless the DLL understands a special type called a
SAFEARRAY".
I think the char *fileName is where the problem lies.

Perhaps. I simply don't know.

how do you present char *fileName in vb:

You might be able to get an answer to this question by doing a Google
Advanced Groups search for groups that deal with Visual Basic 6 questions.


Tom Wickerath
Microsoft Access MVP
http://www.accessmvp.com/TWickerath/
http://www.access.qbuilt.com/html/expert_contributors.html
__________________________________________
 
J

James A. Fortune

Mark said:
I have an sdk that I need to use (secbank.dll to access the Biometrika
Fx3000 fingerprint scanner)

I have had to covert from the 'C' header file sample into a VB DLL
function, but I've obviously go it wrong because Access keeps on
crashing.

I think the problem is with 'fileName' parameter - any obvious mistake?
(the maximum file length is 16 characters)


C ORIGINAL:

SECBANKDLL_API UINT SB_CALLMODE SecBank_Create (Device Disp, char
*fileName, DWORD *IDSecBank, BYTE *Pin, DWORD lenPin); //Creates a new
SecBank on the scanner RAM


VB:

Public Declare Function SecBank_Create Lib "SecBank.dll" (ByVal Device
As Long, ByVal afileName As Byte, ByVal aIDSecBank As Long, ByRef aPin
As Byte, ByVal lenPin As Long) As Integer 'Creates a new
SecBank on the scanner RAM


Code:
Dim RetV As Long
Dim SB_ID As Long
Dim PinArr() As Byte
Dim FileName() As Byte
Const IDDevFlashScanner As Long = 1
Const Pin As String = "12345678901234567890123456789012"
Const FName As String = "FileName00123456"
PinArr() = StrConv(Pin, vbFromUnicode)
FileName() = StrConv(FName, vbFromUnicode)
RetV = SecBank_Create(IDDevFlashScanner, FileName(0), SB_ID,
PinArr(0), 32)
If RetV <> 0 Then Call FPErrMsg(RetV)

Unsigned integers require special handling. See:

Win32 API Programming with Visual Basic
Roman, Steven
Copyright 2000
O'Reilly & Associates
ISBN: 1-56592-631-5

especially Chapter 5. There might be a later version since I view it as
an eBook, but the book is more than well worth buying. In fact, I
consider it the most useful computer book I've ever read. I believe
that it will address all the issues you face with your API call from VBA.

James A. Fortune
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top