Results 1 to 7 of 7

Thread: passing structs

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2000
    Location
    Ireland, Dublin
    Posts
    76

    Talking passing structs

    Hi,

    I am looking for a way to pass structs or a similar type of thing from a C++ DLL to VB.

    Has anyone got any ideas.....

    Regards

    IJ...
    ---------------------------------
    TopMan
    ---------------------------------

  2. #2
    Fanatic Member twanvl's Avatar
    Join Date
    Dec 2001
    Posts
    771
    You could do it the way windows API does it:

    C++:
    Code:
    struct my_struct
    {
        int a,b;
        char c;
        something* d;
    };
    void _stdcall my_function(my_struct& the_struct)
    {
        the_struct.a=1;
        the_struct.b=2;
        the_struct.c="3";
        the_struct.d=&my_something;
    }
    VB:
    VB Code:
    1. Type my_struct
    2.     'The same as the other struct, but VB doesn't have pointers so use a Long instead
    3.     Long a
    4.     Long b
    5.     Byte c
    6.     Long d
    7. End Type
    8. Declare Sub my_function Lib "dll.dll" (ByRef Struct As my_struct)
    9. Sub MySub()
    10.     Dim ReturnValue As my_struct
    11.     my_function ReturnValue
    12.     MsgBox ReturnValue.a
    13. End Sub

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Jul 2000
    Location
    Ireland, Dublin
    Posts
    76
    Thanks man, your a genius

    But how do I get the string value, not too sure about that

    Thanks

    IJ...
    ---------------------------------
    TopMan
    ---------------------------------

  4. #4
    Fanatic Member twanvl's Avatar
    Join Date
    Dec 2001
    Posts
    771
    A VB string passed ByVal can be used in C++ as a normal wchar_t:
    Code:
    #include <string>
    #include <algorithm>
    void _stdcall takes_a_string(wchar_t* the_string)
    {
        std::wstring my_string = the_string;
        the_string=L"hi" + L", bye";
        std::copy(my_string.begin(),my_string.end(),the_string);
        the_string[my_string.size()]=0;
    }
    You could also use C style string functions instead of the C++ ones. Also, make sure that the string is large enough, and that it is not a variant:
    VB Code:
    1. Declare Sub takes_a_string Lib "dll.dll" (ByVal aString as String)
    2. Sub MyOtherSub()
    3.     Dim MyString As String
    4.     MyString=String(100," ") ' Make sure it is large enough
    5.     takes_a_string MyString
    6.     ' Everything until the \0, which markes the end of a C style string
    7.     MyString=Left$(MyString,InStr(MyString,vbNullChar)-1)
    8.     MsgBox MyString
    9. End Sub
    Also note that although you are passing the string ByVal, you can still modify it in C++
    I don't know if it also works for a string in a struct...

  5. #5
    Junior Member
    Join Date
    Oct 2002
    Location
    MI
    Posts
    23
    Could pointers (in C) be used for something like this?

  6. #6
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    You mean, to pass strings? Maybe. Actually quite possible...

    Why not try? Use VarPtr, or Copymemory!
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  7. #7
    Fanatic Member sbasak's Avatar
    Join Date
    Aug 2001
    Location
    Globe Trotter
    Posts
    524
    The example creates shows how to

    1. create a DLL in C/C++ which returns a structure
    2. calls that DLL in VB (using VarPtr and CopyMemory)

    [ccode]
    #include<string.h>
    #include<math.h>
    #include<malloc.h>
    struct quad
    {
    float r1;
    float r2;
    char* status;
    };
    quad* _stdcall solve_quad(int *a);
    quad* _stdcall solve_quad(int *a)
    {
    quad *x;
    x=(quad*)malloc(sizeof(quad));
    int p,q,r;
    float determ;
    p=*(a+0);
    q=*(a+1);
    r=*(a+2);
    determ=q*q-4*p*r;
    if(determ<0) /* no real root */
    {
    x->r1=0;
    x->r2=0;
    x->status=(char*)malloc(13*sizeof(char));
    strcpy(x->status,"No real root");
    return x;
    }
    else /* real root exists */
    {
    x->r1=((-q)+sqrt(determ))/(2*p);
    x->r2=((-q)-sqrt(determ))/(2*p);
    x->status=(char*)malloc(15*sizeof(char));
    strcpy(x->status,"Two real roots");
    return x;
    }
    }
    [/ccode]

    Create also the .def file as usual.
    LIBRARY ArrayStructure
    EXPORTS solve_quad

    Now use the following code to call the function in VB.

    VB Code:
    1. Private Declare Sub CopyMemory Lib "kernel32" Alias
    2. "RtlMoveMemory" _
    3. (Destination As Any, ByVal Source As Any, ByVal Length As
    4. Long)
    5. Private Declare Function solve_quad Lib "arraystructure.dll" _
    6. (ByVal m As Long) As Long
    7. Private Sub Command1_Click()
    8. Dim adr As Long
    9. Dim z(3) As Long
    10. Dim Root1 As Single
    11. Dim Root2 As Single
    12. Dim Solution As String
    13. z(0) = 1
    14. z(1) = -5
    15. z(2) = 6
    16. adr = solve_quad(VarPtr(z(0)))
    17. Call CopyMemory(Root1, adr, 4)
    18. Call CopyMemory(Root2, adr + 4, 4)
    19. Call CopyMemory(Solution, adr + 8, 4)
    20. MsgBox "Root1 = " & Root1 & vbCrLf & "Root2 = " & Root2 _
    21. & vbCrLf & "Solution = " & Solution
    22. End Sub

    Execute the VB program and you’ ll see two roots and status of solution.
    Life is a one way journey, not a destination. Travel it with a smile and never regret anything.
    Yesterday is history, tomorrow is a mystery, today is gift - that's why we call it present.

Posting Permissions

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



Click Here to Expand Forum to Full Width