Avatar of Harsh08
Harsh08
 asked on

c dll calling from VB6 - Parameter Error

Private Declare Function SSR_GetGeneralLogData Lib "c:\Windows\System32\zkemkeeper.DLL" (ByVal dwMachineNumber As Long, _
ByVal dwEnrollNumber As String, ByVal dwSize As Long, ByVal dwVerifyMode As Long, _
ByVal dwInOutMode As Long, ByRef dwYear As Long, ByRef dwYear As Long, ByRef dwMonth As Long, ByRef dwDay As Long, ByRef dwHour As Long, ByRef dwMinute As Long, ByRef dwsecond As Long, ByRef dwWorkCode As Long) As Boolean

 Dim ver As String
    Dim vMachineNumber
    Dim dwEnrollNumber As String
    Dim dwVerifyMode As Long
    Dim dwInOutMode As Long
    Dim timeStr As String
    Dim i As Long
    Dim dwMachineNum As Long
    Dim dwEMachineNum As Long
    Dim dwYear As Long
    Dim dwMonth As Long
    Dim dwDay As Long
    Dim dwHour As Long
    Dim dwMinute As Long
    Dim dwsecond As Long
    Dim dwWorkCode As Long
    Dim dwReserved As Long
   
     Dim s As String
 
    'DLL PARAMETERS
    '[in] LONG dwMachineNumber,
    '[out] BSTR* dwEnrollNumber,
    '[out] LONG* dwVerifyMode,
    '[out] LONG* dwInOutMode,
    '[out] LONG* dwYear,
    '[out]LONG* dwMonth,
    '[out] LONG* dwDay,
    '[out] LONG* dwHour,
    '[out] LONG* dwMinute,
    '[out] LONG* dwSecond,
    '[out,retval] VARIANT_BOOL* pVal

   
    If CZKEM1.ReadGeneralLogData(1) Then
        BUFFER OVERRUN AFTER EXECUTING FOLLOWING LINE

        While CZKEM1.SSR_GetGeneralLogData(1, dwEnrollNumber, dwVerifyMode, dwInOutMode, dwYear, dwMonth, dwDay, dwHour, dwMinute, dwsecond, dwWorkCode)



        DoEvents
        i = i + 1
        'Write to database
       
        'MsgBox strSQL
'''''''            dbs.Execute strSQL, dbFailOnError
        Wend
        End If
        MsgBox "Processed Successfully!"
    End If
Visual Basic ClassicCVisual Basic.NET

Avatar of undefined
Last Comment
Martin Liss

8/22/2022 - Mon
GrahamSkan

Try declaring dwEnrollNumber as a fixed-length string, large enough to accommodate the expected text, e.g.

Dim dwEnrollNumber As String * 100
Harsh08

ASKER
Tried it but same error
jkr

Since it is a 'BSTR*' (i.e. a pointer), you should IMHO declare that as 'ByRef'.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Harsh08

ASKER
Thnx...
But I have tried that even....
& I have an application installed, which works fine with this dll
shorvath

From this link:

http://msdn.microsoft.com/en-us/library/aa263531%28v=vs.60%29.aspx

Some DLLs may be written specifically to work with Automation data types like BSTR, using procedures supplied by Automation.

Because Visual Basic uses Automation data types as its own data types, Visual Basic arguments can be passed by reference to any DLL that expects Automation data types. Thus, if a DLL procedure expects a Visual Basic string as an argument, you do not need to declare the argument with the ByVal keyword, unless the procedure specifically needs the string passed by value.

Some DLL procedures may return strings to the calling procedure. A DLL function cannot return strings unless it is written specifically for use with Automation data types. If it is, the DLL probably supplies a type library that describes the procedures. Consult the documentation for that DLL.

A DLL procedure can modify data in a string variable that it receives as an argument. However, if the changed data is longer than the original string, the procedure writes beyond the end of the string, probably corrupting other data.

You can avoid this problem by making the string argument long enough so that the DLL procedure can never write past the end of it


Then try

Dim dwEnrollNumber As String * 255
HooKooDooKu

I've never had to do exactly what you are trying, but my experience says that your best bet might be to:
1. Change your declaration for the parameter to 'ByRef'
2. Rather than passing 'dwEnrollNumber', try passing 'VarPtr( dwEnrollNumber )'

Private Declare Function SSR_GetGeneralLogData Lib "c:\Windows\System32\zkemkeeper.DLL" (ByVal dwMachineNumber As Long, _
ByRef dwEnrollNumber As String, ByVal dwSize As Long, ByVal dwVerifyMode As Long, _
ByVal dwInOutMode As Long, ByRef dwYear As Long, ByRef dwYear As Long, ByRef dwMonth As Long, ByRef dwDay As Long, ByRef dwHour As Long, ByRef dwMinute As Long, ByRef dwsecond As Long, ByRef dwWorkCode As Long) As Boolean

While CZKEM1.SSR_GetGeneralLogData(1, VarPtr(dwEnrollNumber), dwVerifyMode, dwInOutMode, dwYear, dwMonth, dwDay, dwHour, dwMinute, dwsecond, dwWorkCode)
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
HooKooDooKu

A few follow up details:

When you pass a VB String to a dll ByVal, you don't really pass it "By Value".  What actually happens is that the VB Unicode String is converted to ANSI and a char* of the ANSI string is sent to the dll.  When the function returns, the ANSI string at the char* is converted into a VB Unicode String and the original VB String is updated with the new value.  So in reality, passing a VB String ByVal still passes ByRef.  And BTW, if the dll makes the char* longer, bad things can happen when VB goes to return the results back into the original string.

When you pass a VB String to a dll ByRef, I believe that a BSTR is sent to the dll.  I don't know that I've ever passed a VB String ByRef, but I do know that if you declare a dll function as returning a BSTR (and not a BSTR*) that you can have code that looks like this:

Declare Function DllThatReturnsBSTR() as String
Dim Str
Str = DllThatReturnsBSTR();

And finally, it's widely known today, but there is a 'hidden' function in VB,  VarPtr().  It returns a pointer to the variable.
HooKooDooKu

Oh, and now that I remembered the VarPtr function, you might also try replacing the VarPtr I listed above with either StrPtr or ObjPtr.  Don't know if they will work, but StrPtr is defined as "gives the memory address of the contents of a string".  That might just be the BSTR* (but I'm not sure).  But it is worth a try.

http://www.codeproject.com/Articles/5685/Pointers-in-Visual-Basic-using-Undocumented-Functi
HooKooDooKu

One last idea.  Try changing the declare to 'ByRef' and 'As Any').

Private Declare Function SSR_GetGeneralLogData Lib "c:\Windows\System32\zkemkeeper.DLL" (ByVal dwMachineNumber As Long, _
ByRef dwEnrollNumber As Any, ByVal dwSize As Long, ByVal dwVerifyMode As Long, _
ByVal dwInOutMode As Long, ByRef dwYear As Long, ByRef dwYear As Long, ByRef dwMonth As Long, ByRef dwDay As Long, ByRef dwHour As Long, ByRef dwMinute As Long, ByRef dwsecond As Long, ByRef dwWorkCode As Long) As Boolean

The try passing the original variable: dwEnrollNumber
and try passing the pointer to the original value: VarPtr( dwEnrollNumber )
and try passing the pointer to the contents: StrPtr( dwEnrollNumber )
and finally the pointer to the object: ObjPtr( dwEnrollNumber ).

Again, I've never had to try exactly what you are doing (and currently don't have any test code or the time to look for the exact solution).  But one of those combinations should eventually work.


Just to rehash:
1. Try declaring the variable ByRef and ByVal
2. Try declaring the variable 'As String' and 'As Any'
3. Try passing the variable, VarPtr(variable), StrPtr(variable), and ObjPtr(variable).

Try all the possible combinations of these options.  If it still does not work, then the last thing I can think of:

Declare the variable ByVal and As Long (good for passing pointer) and pass VarPtr, StrPtr, and ObjPtr.


Otherwise, the only other thing I can even contemplate on how to fix the issue involved changing the dll (to take something OTHER than a BSTR*... such as a BSTR or char* instead).
3. Also try 'ByRef dwEnrollNumber As Long' (good for passing pointers).
4.

and finally try passing the
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ASKER CERTIFIED SOLUTION
HooKooDooKu

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Martin Liss

This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.