CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Jul 2012
    Posts
    5

    Re: Passing UDT from VB 6.0 to C++ DLL

    I have the same problem as this topic.

    here is the DLL info.

    Code:
    extern "C" __declspec(dllexport) int GetHash(HASHINFO*);
    Code:
    typedef struct {
            unsigned char* pHash;      // Address of buffer for saving hash
            unsigned char* szPassword; // Password
            int nPasswordLen;          // Password length
            unsigned char* szSalt;     // Salt
            int nSaltLen;              // Salt length
            unsigned char* szName;     // User name
            int nNameLen;              // User name length
            DWORD dwFlags;             // Flags
    } HASHINFO;
    Here is the VB

    Code:
    Private Type HASHINFO
       hash As String
       szPassword As String * 10
       nPasswordLen As Long
       szSalt As String * 10
       nSaltLen As Long
       szName As String * 10
       nNameLen As Long
       dwFlags As Long
    End Type
    
    Private Declare Sub GetHash Lib "c:\md5\md5.dll" (ByRef pudt As HASHINFO)
    Code:
    Private Sub Command1_Click()
    Dim udt As HASHINFO
       udt.hash = vbNullString
       udt.szPassword = "test" & Chr(0)
       udt.nNameLen = 4
       udt.szSalt = "test" & Chr(0)
       udt.nSaltLen = 4
       udt.szName = "test" & Chr(0)
       udt.nNameLen = 4
       udt.dwFlags = 0
    Call GetHash(udt)
    End Sub
    I just get a crash.

    Anyone out there to help me?
    Last edited by GremlinSA; July 10th, 2012 at 03:58 AM.

  2. #2
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,675

    Re: Passing UDT from VB 6.0 to C++ DLL

    [Split Topic]
    Please Start your own thread, and you can add reference to older topic...
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  3. #3
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,675

    Re: Passing UDT from VB 6.0 to C++ DLL

    Code:
    typedef struct {
            unsigned char* pHash;      // Address of buffer for saving hash  <-- Variable Length
            unsigned char* szPassword; // Password  <-- Variable Length
            int nPasswordLen;          // Password length <-- Defined length of char array
            unsigned char* szSalt;     // Salt  <-- Variable Length
            int nSaltLen;              // Salt length <-- Defined length of char array
            unsigned char* szName;     // User name  <-- Variable Length
            int nNameLen;              // User name length <-- Defined length of char array
            DWORD dwFlags;             // Flags
    } HASHINFO;
    Code:
    Private Type HASHINFO
       hash As String  '<--- Variable Length
       szPassword As String * 10 '<--- Fixed Length
       nPasswordLen As Long
       szSalt As String * 10  '<--- Fixed Length
       nSaltLen As Long
       szName As String * 10  '<--- Fixed Length
       nNameLen As Long
       dwFlags As Long
    End Type
    Made a few pointers here ... Notice what i'm pointing out...

    Another one is ..
    C++ Int = 4 bytes..
    VB6 Long = 8 Bytes..

    Your two data types need to match up exactly, so that the External C DLL can correctly parse out the info .

    Code:
    Private Sub Command1_Click()
    Dim udt As HASHINFO
       udt.hash = vbNullString
       udt.szPassword = "test" & Chr(0)  ' <-- using 5 of the 10 allocated..
       udt.nNameLen = 4                ' <--- Wrong Variable used in here......
       udt.szSalt = "test" & Chr(0)  ' <-- using 5 of the 10 allocated..
       udt.nSaltLen = 4                ' <-- Saying Prev Char is only 4 long when its defined as 10 long..
       udt.szName = "test" & Chr(0) ' same here
       udt.nNameLen = 4                ' Same Here...
       udt.dwFlags = 0
    Call GetHash(udt)
    End Sub
    this should help you fix it...
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  4. #4
    Join Date
    Jul 2012
    Posts
    5

    Re: Passing UDT from VB 6.0 to C++ DLL

    Thanks for checking thigns out.

    I'm pretty sure VB Long is 4 bytes, Double is 8 bytes.

    I have tried this

    Code:
    Public Type HASHINFO
       pHash As String
       szPassword As String
       nPasswordLen As Long
       szSalt As String
       nSaltLen As Long
       szName As String
       nNameLen As Long
       dwFlags As Long
    End Type
    
    Public Declare Function GetHash Lib "C:\md5\md5.dll" (ByRef xx As HASHINFO) As Long
    Call code:

    Code:
    Private Sub Command1_Click()
    Dim test as long
    
    Dim udt As HASHINFO
    
        udt.szPassword = "test"
        udt.nPasswordLen = 4
        udt.szSalt = "test"
        udt.nSaltLen = 4
        udt.szName = "test"
        udt.nNameLen = 4
        udt.dwFlags = &H0
        
    test = GetHash(udt)
    
    End Sub
    I'm not sure if I need to specify something for udt.pHash, have tried various things and it still crashes.

  5. #5
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,675

    Re: Passing UDT from VB 6.0 to C++ DLL

    Quote Originally Posted by user65536 View Post
    Thanks for checking thigns out.

    I'm pretty sure VB Long is 4 bytes, Double is 8 bytes.
    you actually are right.. VB.NET Long = 8 bytes in VB6 = 4 bytes.. Havn't done VB6 in a long time..


    Quote Originally Posted by user65536 View Post
    I have tried this

    Code:
    Public Type HASHINFO
       pHash As String
       szPassword As String
       nPasswordLen As Long
       szSalt As String
       nSaltLen As Long
       szName As String
       nNameLen As Long
       dwFlags As Long
    End Type
    
        Dim udt As HASHINFO
    
        udt.szPassword = "test"
        udt.nPasswordLen = 4
        udt.szSalt = "test"
        udt.nSaltLen = 4
        udt.szName = "test"
        udt.nNameLen = 4
        udt.dwFlags = &H0
        
    test = GetHash(udt)
    
    End Sub
    I'm not sure if I need to specify something for udt.pHash, have tried various things and it still crashes.
    You will need to assign the right amount of space for the Hash to be put in (32 Byte hash ?) as the C DLL cannot assign new/ more memory to the referenced Datatype.

    You were on the right track with the Null (&H0) termination..

    But something else i'm thinking is that VB stores stings in Unicode (2 bytes per char) and the char array in C is expecting one byte per char.. (this may need clarification from a C Expert) ...

    in this case an array of byte may be better to use, and you load the ASCII val of each char in the string to the byte array..

    You will have to play with it a little, if your Defs and Variable lengths are out by one, it will crash ...

    try this for debugging
    Code:
     Debug.print len(udt)
    After you've assigned all the values and then see if it matches what you should have...
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  6. #6
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,722

    Re: Passing UDT from VB 6.0 to C++ DLL

    In my opinion the strings in the UDT should either be of fixed length or, if dynamic, they must be initialized.
    If you expect a string to be filled in by the dll yo must provide enough buffer space for the resulting string.
    If udt.pHash is the string where you expect the result to be returned, you have to preallocate space like
    Code:
    Private Sub Command1_Click()
    Dim test as long
    
    Dim udt As HASHINFO
        udt.pHash = Space$(256) '<---- preallocate a buffer of 256 characters
        udt.szPassword = "test"
        udt.nPasswordLen = 4
        udt.szSalt = "test"
        udt.nSaltLen = 4
        udt.szName = "test"
        udt.nNameLen = 4
        udt.dwFlags = &H0
        
    test = GetHash(udt)
    
    End Sub
    If this fails you try to declare pHash as a constant length string, like in your first version you did with the other strings
    Code:
    Public Type HASHINFO
       pHash As String * 256
       ....
    The length of the string depends on how many characters you expect to be returned.

  7. #7
    Join Date
    Jul 2012
    Posts
    5

    Re: Passing UDT from VB 6.0 to C++ DLL

    in order to determine how many bytes pHash is suppose to be buffered the dll call was attempted in c.

    It appears that only

    szPassword
    nPasswordLen

    are the necessary inputs

    while pHash returns a Byte Array of (16 bytes), this byte array needs to be then converted to hex to give the full 32byte hexstring of the hash.

    The VB Code was then modified to reflect this.

    Code:
    Private Sub Command1_Click()
    Dim test as long
    
    Dim udt As HASHINFO
        udt.pHash = Space$(16) 
        udt.szPassword = "test"
        udt.nPasswordLen = 4
    
    test = GetHash(udt)
    
    End sub

    Code:
    Public Type HASHINFO
       pHash As String * 16
       szPassword As String * 4
       nPasswordLen As Long
    End Type
    
    Public Declare Function GetHash Lib "C:\md5\md5.dll" (ByRef xx As HASHINFO) As Long
    Too bad it still crashes.

  8. #8
    Join Date
    Dec 2001
    Posts
    6,313

    Re: Passing UDT from VB 6.0 to C++ DLL

    Quote Originally Posted by user65536 View Post
    here is the DLL info.

    Code:
    extern "C" __declspec(dllexport) int GetHash(HASHINFO*);
    Code:
    typedef struct {
            unsigned char* pHash;      // Address of buffer for saving hash
            unsigned char* szPassword; // Password
            int nPasswordLen;          // Password length
            unsigned char* szSalt;     // Salt
            int nSaltLen;              // Salt length
            unsigned char* szName;     // User name
            int nNameLen;              // User name length
            DWORD dwFlags;             // Flags
    } HASHINFO;
    Here is the VB

    Code:
    Private Type HASHINFO
       hash As String
       szPassword As String * 10
       nPasswordLen As Long
       szSalt As String * 10
       nSaltLen As Long
       szName As String * 10
       nNameLen As Long
       dwFlags As Long
    End Type
    
    Private Declare Sub GetHash Lib "c:\md5\md5.dll" (ByRef pudt As HASHINFO)
    Code:
    Private Sub Command1_Click()
    Dim udt As HASHINFO
       udt.hash = vbNullString
       udt.szPassword = "test" & Chr(0)
       udt.nNameLen = 4
       udt.szSalt = "test" & Chr(0)
       udt.nSaltLen = 4
       udt.szName = "test" & Chr(0)
       udt.nNameLen = 4
       udt.dwFlags = 0
    Call GetHash(udt)
    End Sub
    I just get a crash.

    Anyone out there to help me?
    What jumps out at me first is that the DLL UDT structure given above says (for the hash string) "Address of buffer for saving hash". That to me means it's a reference to the memory where the string is stored, not the actual string itself. If true, then might the VB UDT structure use a Long, not a string? Whichever it is, the other string members would be the same, no?

    So basically, if the hash member and the string members are of the same type, you can't make them different in VB. They either have to both be fixed length strings, or variable length strings.

    Incidentally, VB pads fixed length strings with zeros (Chr$(0) or vbNullChar) if you don't assign all the available characters. The value returned by Len(TheUDT) will always be the length of the structure in memory. When fixed length strings are defined in a UDT, the actual string is stored in the space allocated for the structure, thus will be included in the value returned by Len. On the other hand, variable length strings are not stored within the space in memory for the structure, because the string member is a reference to the location of the string, not the actual string.
    Please remember to rate the posts and threads that you find useful.
    How can something be both new and improved at the same time?

  9. #9
    Join Date
    Jul 2012
    Posts
    5

    Re: Passing UDT from VB 6.0 to C++ DLL

    Ok since i can use StrPrt and VarPtr to pass references I may be able to pass PHash as long. So this is what is tried.

    According to: http://www.xtremevbtalk.com/showthread.php?t=230453 I must pass with VtrPtr rather than StrPtr to return pointer of the BSTR so this is what I tried.

    Call Code:

    Code:
    Private Sub Command1_Click()
    
    testString = Space$(16)
    
    Dim udt As HASHINFO
        
        udt.pHash = VarPtr(testString)
        udt.szPassword = "test"
        udt.nPasswordLen = 4
        
    test = GetHash(udt)
    
    MsgBox udt.pHash
    End Sub
    Code:
    Public Type HASHINFO
       pHash As Long
       szPassword As String
       nPasswordLen As Long
    End Type
    
    Public Declare Function GetHash Lib "C:\md5\md5.dll" (ByRef udt As HASHINFO) As Long
    
    Public testString As String * 16
    Crash.

    Looks like i'm following everything correctly.

    -Buffered string to 16 bytes which I know is the return size
    -Passing the references of the string as long from VB
    -Only passing requires inputs for DLL others were omitted

    I guess this dll probably just isn't callable from VB6

  10. #10
    Join Date
    Jan 2006
    Location
    Chicago, IL
    Posts
    14,610

    Re: Passing UDT from VB 6.0 to C++ DLL

    As I've said. Pointers can rarely be used from C++ (unless it was specifically written to pass a pointer AND a string)
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2012 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  11. #11
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,675

    Re: Passing UDT from VB 6.0 to C++ DLL

    Here are some hints to match up a UDT, from C to VB6.....

    Use Array of Byte instead of Strings, to match array of char ( VB uses Unicode to store a string, 2 Bytes per Char + 2 bytes for length)

    Match the Length Variable Exactly to the length of the matching Byte array.

    use something along the lines of...
    Code:
        udt.nPasswordLen = length(udt.szPassword)
    Do not forget to add a Null terminator to the last position in the variable been used for strings...
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  12. #12
    Join Date
    Dec 2001
    Posts
    6,313

    Re: Passing UDT from VB 6.0 to C++ DLL

    If you didn't change the declaration of the UDT so that pHash is a Long instead of a String, then it'll still have the same result. And again, it follows that the others would need to be the same.

    I may just get curious enough to try some stuff with it myself.
    Please remember to rate the posts and threads that you find useful.
    How can something be both new and improved at the same time?

  13. #13
    Join Date
    Jul 2012
    Posts
    5

    Re: Passing UDT from VB 6.0 to C++ DLL

    MD.zip

    Well for anyone who wants to give this a shot.

    Here are the files. You will need to move the dll into the correct area.

    Thanks

  14. #14
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,675

    Re: Passing UDT from VB 6.0 to C++ DLL

    Played with it a little..

    and got a little news for ya..

    The Dll is not properly compiled for VB calling... (see this thread on VB forums for what i mean)

    Right so this is the story...
    The proper UDT you need is like this..

    Code:
    Public Type HASHINFO
       pHash() As Byte
       szPassword() As Byte
       nPasswordLen As Long
       szSalt() As Byte
       nSaltLen As Long
       szName() As Byte
       nNameLen As Long
       dwFlags As Long
    End Type
    and to use it your code is like this...
    Code:
    Dim udt As HASHINFO
        ReDim udt.pHash(16)
        ReDim udt.szName(1)
        ReDim udt.szPassword(5)
        ReDim udt.szSalt(1)
        
        udt.nNameLen = 1
        udt.szName(0) = 0
        udt.nSaltLen = 1
        udt.szSalt(0) = 0
        udt.nPasswordLen = 5
        udt.szPassword(0) = Asc("t")
        udt.szPassword(1) = Asc("e")
        udt.szPassword(2) = Asc("s")
        udt.szPassword(3) = Asc("t")
        udt.szPassword(4) = 0
    Problem is now you get a Error 49 - Bad DLL calling convention..
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  15. #15
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,722

    Re: Passing UDT from VB 6.0 to C++ DLL

    If the calling convention is bad (no STDCALL) then also the string-constant versions of the UDT might work, as long as the calling convention is adapted or changed.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



HTML5 Development Center

Click Here to Expand Forum to Full Width