VB Declare blues pt 2

I thought I had it under control but no…
Here’s another translation from VB that I can not get to work, using declares… in this case the problem is the usage of BYTE as a datatype.

VB6 code
Example1

[code]
Private Declare Function GetVersionInfo Lib “IDCard.dll” (ByRef lpBuffer As Byte, ByVal nBufferLenth As Long) As Long

Dim MAX_CH_NUM As Long
MAX_CH_NUM = 50
Dim strTmp(50) As Byte

    nRet = GetVersionInfo(strTmp(0), MAX_CH_NUM)
    ResultTextBox.Text = strTmp[/code]

Example2

[code]
Private Declare Function GetRecogResult Lib “IDCard.dll” (ByVal nIndex As Long, ByRef lpBuffer As Byte, ByRef nBufferLen As Long) As Long

Private Declare Function GetFieldName Lib "IDCard.dll" (ByVal nIndex As Long, ByRef llpBuffe As Byte, ByRef nBufferLen As Long) As Long

Dim MAX_CH_NUM As Long
MAX_CH_NUM = 128
Dim szFieldValue(255) As Byte
Dim szFieldName(255) As Byte

    Dim nIndex As Long
    nIndex = 1
    ResultTextBox.Text = "recognition successful" & vbCrLf
    Dim output As Long
    output = 1
    Do While (output)
        If nRet <> 3 Then
            Dim strTmp(255) As Byte
            Dim strTmp1(255) As Byte
           
           
            nRet = GetRecogResult(nIndex, szFieldValue(0), MAX_CH_NUM)
           

            Dim nnRet As Long
            nnRet = GetFieldName(nIndex, szFieldName(0), MAX_CH_NUM)
          
            Dim strFieldName As String
            
            If nnRet = 0 Then
                strFieldName = szFieldName
                ResultTextBox.Text = ResultTextBox.Text + strFieldName
                ResultTextBox.Text = ResultTextBox.Text + ":  "
                strFieldName = szFieldValue
                ResultTextBox.Text = ResultTextBox.Text + strFieldName
                ResultTextBox.Text = ResultTextBox.Text + vbCrLf 

            End If
    
           nIndex = nIndex + 1
        Else
            output = 0

        End If


    Loop[/code]

I am not sure where to start… first… what si the analogous to BYTE in xojo ? and also why szFieldValue and szFieldName have a value between parenthesis… is this an offset ? o r some kind of array ?

I imagine I have to use memblocks ?
Can anyone help ?
I need to get this dll working…

TIA
Roman

BYTE is usually a UINT8
But szFieldValue(255) becomes a new memoryblock(255)… the 255 tells vb to make the string exactly 255 bytes long
And a memoryblock can be addressed like an array of bytes mb.byte(6) for example

In this case you expect a string, so just take the stringvalue of the memoryblock

Try this

[quote=367306:@Jeff Tullin]BYTE is usually a UINT8
But szFieldValue(255) becomes a new memoryblock(255)… the 255 tells vb to make the string exactly 255 bytes long
And a memoryblock can be addressed like an array of bytes mb.byte(6) for example

In this case you expect a string, so just take the stringvalue of the memoryblock[/quote]

and use

Soft Declare Function GetVersionInfo Lib "IDCard.dll" (lpBuffer As ptr, nBufferLenth As Integer) As Integer

Soft Declare Function GetRecogResult Lib "IDCard.dll" (nIndex As Integer, lpBuffer As ptr, ByRef nBufferLen As Integer) As Integer
   
Soft Declare Function GetFieldName Lib "IDCard.dll" (nIndex As Integer, llpBuffe As ptr, ByRef nBufferLen As Integer) As Integer

Hey Jeff. thanks for the reply… not sure I got it right, though…

Let’s take this example from the API documentation…

BOOL WINAPI GetVersionInfo(LPWSTR lpBuffer,int nBufferLen)

Function Get the SDK Version
lpBuffer Save the version information , the memory size should not be less than 100 bytes
nBufferLen the memory size of the “lpBuffer” Return value TURE for success FALSE for failure

I tried this code in Xojo… but did not work…

[code] Dim lpBuffer as WString

Declare Function GetVersionInfo Lib “IDCard.dll” (ByRef lpBuffer as wstring, nBufferLenth As integer) As integer

nRet = GetVersionInfo(lpBuffer, 128)

ResultTextBox.Text = lpBuffer[/code]

I also tried passing a memory block… but objects can’t used within declares…

You may want to buy the “Xojo Declares for Win32” book by Eugene Dakin at http://xdevlibrary.com/

Declare Function GetVersionInfo Lib "IDCard.dll" (lpBuffer as ptr, nBufferLenth As integer) As integer

Dim lpBuffer as new MemoryBlock(128) 
nRet = GetVersionInfo(lpBuffer, lpBuffer.size)

ResultTextBox.Text = lpBuffer.WString(0)

@Michel Bujardet : I just got the book… I am trying to dive into the concepts but I am not familiar with declares… so it’s gonna take some time…

@Asis Patisahusiwa : Thanks. That works… Hopefully this and Eugene’s book will get me strated :slight_smile:

You can also download the Windows Functionality Suite, which contains numerous declares.
https://github.com/arbp/WFS

Thanks Michael… I think I have it somewhere…
Again thanks a lot for the help… I’ve been stuck with this for hours, trying to learn it on my own…

Hi Roman,

I can help you if you would like. I will be near my development computer in a couple of hours. Do you happen to have a download link for the ‘idcard.dll’ file?

Happy to help.

Hey Eugene… just bought your book :slight_smile:

I got it working now, thanks to the help from the folks in this forum… I will begin reading the book later tonight for a deeper understanding of the concept.

If I need further help, I’ll knock on your door

Thaaanks!!
R

In my experience, declares are better consumed in small sips.

Better do some, then smell the roses, sleep on it, and resume the next day.

Don’t try to go too fast. Make sure you understand fully before jumping to something else. Soon enough, you will feel comfortable.

Study WFS, or simply pick from it. It is a good code read.

And of course, Eugene book :slight_smile:

I’ve one more question…

Is it ok to create a method for each declare… and the call this method every time I need to interact with the API (and then when the method ends the declare goes out of scope) ?

Or this there something like VB’s general (Global) declarations where all declares go together once ?

I like how they say 100 bytes in the doc then give an example with 50… facepalm

Just make sure you’re setting aside enough space for the returned data.

If they are sending back up to 100 “characters” and you’re receiving them in wide format (UTF-16) then I’d suggest doubling their 100 byte request to at least 200 bytes in your receive buffer length.

It’s interesting that they spec byte then Asis’ example works with WString (which is 2 bytes per character), its almost like they have updated the dll to Unicode and not updated the docs.

Fun fun :slight_smile:

PS. See https://blog./2017/01/22/windows-to-xojo-data-type-conversion/ if you want a searchable list for future declares. I’m glad you picked up Eugene’s book, its very handy :slight_smile:

PPS. https://forum.xojo.com/conversation/post/367317 would have worked if you had pre-filled lpBuffer with 128 spaces before the call, but memoryblocks are neater and more versatile solution :slight_smile:

I only follow this code. I assume that he want to get unicode character and the buffer is large enough :slight_smile:

There is a global function in Xojo where the declare can be created. Here are the steps:

  1. Add a module to your project
  2. right mouse click the module and select: Add To Module1->External Method, and add the name, parameters, return type, library, and alias values.

This will only need to be performed once for the project.