Results 1 to 12 of 12

Thread: Structure Conversion between VB6 and C

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Sep 2012
    Posts
    433

    Structure Conversion between VB6 and C

    My VB6 program should call C DLL.
    I should pass structure type as a parameter.
    Original C structure is like following.

    typedef struct strIniSensor
    {
    const char* theInitFile;
    CallBackFunc IniSensorCallBack;
    void * CallBackParameters;
    }strIniSensor;

    I made VB6 side Type Definition like following.
    Type strIniSensor '
    theInitFile As String
    IniSensorCallBack As Long
    CallBackParameters As Long
    End Type

    Is this correct? vensor who provide dll says I can assign NULL to all items(theInitFile,IniSensorCallBack,CallBackParameters) in the structure.

  2. #2
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Structure Conversion between VB6 and C

    Looks OK to me. Your API declaration should pass your structure ByRef.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Sep 2012
    Posts
    433

    Re: Structure Conversion between VB6 and C

    Yes I do pass my structure ByRef.
    Thanks!

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Sep 2012
    Posts
    433

    Re: Structure Conversion between VB6 and C

    I have trouble in other C DLL function call.
    Can somebody review this VB6 code is correct?
    ------------------------------------------------------------------
    <C DLL and calling in C>
    typedef struct strImageAcq
    {
    const char* theHandle;
    char* theImageBuf;
    long* theImageBufSizePtr;
    const struct timeval* theTimeout;
    long ImageStatus;
    CallBackFunc AcqImageCallBack;
    void * CallBackParameters;
    }strImageAcq;

    struct timeval {
    long tv_sec;
    long tv_usec;
    }

    __declspec (dllexport) long TRI_AcqImage(strImageAcq* myImageAcq);

    strImageAcq myImageAcq;
    strImageAcq* ptr_myImageAcq = &myImageAcq;

    myImageAcq.theHandle = theHandle;
    myImageAcq.theImageBuf = theImageBuf;
    myImageAcq.theImageBufSizePtr = &theImageBufSize;
    myImageAcq.theTimeout = &timeout; //This is the time window in which the sensor waits for X-ray, max value 65535 seconds
    myImageAcq.AcqImageCallBack = &MyCallbacFunc;//Pointer to the user defined callback function, can be NULL
    myImageAcq.CallBackParameters = ptr_ImgAcqEvent;//Pointer to the callback function parameters, can be NULL
    myImageAcq.ImageStatus = NULL;//Variable to retrieve image status, 0 is successful

    TRI_AcqImage(ptr_myImageAcq);//This function creats a thread and returns right away
    ------------------------------------------------------------------
    <VB6 declaration and VB6 code>
    Type timeval
    tv_sec As Long 'seconds(long)
    tv_usec As Long 'any micro seconds(long)
    End Type

    Type strImageAcq
    theHandle As Long
    theImageBuf As Byte
    theImageBufSizePtr As Long
    theTimeout As timeval
    ImageStatus As Long
    AcqImageCallBack As Long
    CallBackParameters As Long
    End Type

    Public Declare Function TRI_AcqImage Lib "MyDLL" (myImageAcq As strImageAcq) As Long

    myImageAcq.theHandle = theHandle
    myImageAcq.theImageBuf = theImageBuf(0)
    myImageAcq.theImageBufSizePtr = theImageBufSize
    myImageAcq.theTimeout.tv_sec = timeout.tv_sec
    myImageAcq.theTimeout.tv_usec = timeout.tv_usec
    myImageAcq.ImageStatus = -1
    myImageAcq.AcqImageCallBack = 0
    myImageAcq.CallBackParameters = 0

    lRet = TRI_AcqImage(myImageAcq)

  5. #5
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Structure Conversion between VB6 and C

    Looks OK to me, What 'trouble' are you having?

  6. #6
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Structure Conversion between VB6 and C

    I think you might want something more like this...
    Code:
    Type timeval
       tv_sec As Long 'seconds(long)
       tv_usec As Long 'any micro seconds(long)
    End Type
    
    Type strImageAcq
       theHandle As Long
       ImageBufPtr As long
       ImageBufSizePtr As Long
       TimeoutPtr As Long
       ImageStatus As Long
       AcqImageCallBack As Long
       CallBackParametersPtr As Long
    End Type
    
    '...
    
    Dim myImageAcq As strImageAcq
    
    myImageAcq.theHandle = theHandle
    myImageAcq.ImageBufPtr = VarPtr(theImageBuf(0))
    myImageAcq.ImageBufSizePtr = VarPtr(theImageBufSize)
    myImageAcq.TimeoutPtr = VarPtr(timeout)
    myImageAcq.ImageStatus = -1
    myImageAcq.AcqImageCallBack = 0 'or AddressOf callback function
    myImageAcq.CallBackParametersPtr = 0 'or VarPtr(callBackParams)


    Edit: Be careful with scope, the call could crash your program if any of the pointers refer values that have gone out of scope.
    Last edited by Milk; May 4th, 2013 at 06:09 AM.
    W o t . S i g

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Sep 2012
    Posts
    433

    Re: Structure Conversion between VB6 and C

    I tried this but program crashed.
    You said "be careful with scope". Can you explain more detail about scope?
    If you have some idea, please let me know.

  8. #8
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Structure Conversion between VB6 and C

    Confession; I've not used VB6 in some time.

    The call is asynchronous so it will return almost straight away but it won't be finished until some time later. The pointers in the structure must refer to memory that exists for the duration of the full call. If these are dimensioned at module level (at the top) then they will remain in scope. If these are dimensioned locally (in a sub/function) then they will only remain in scope until the function returns, this might be tricky if you don't know when the async call has finished.

    The callback field can be set to a function pointer which will be called presumably when the call finally completes. I think you can use this in VB6 but if I remember right you can only use AddressOf with API calls so you have to use something like PutMem4 (he's called it PutDWord in the linked page) to get the actual function address.

    How does theHandle work with this dll? It seems a bit strange that is defined as a const char *. Can you show how you get theHandle?
    Last edited by Milk; May 8th, 2013 at 06:41 PM. Reason: did not make sense, awful grammar
    W o t . S i g

  9. #9

    Thread Starter
    Hyperactive Member
    Join Date
    Sep 2012
    Posts
    433

    Re: Structure Conversion between VB6 and C

    That was typo.
    The original structure in C is like this.

    typedef struct strImageAcq
    {
    int theHandle;
    unsigned char* theImageBuf;
    unsigned int* theImageBufSizePtr;
    const struct timeval* theTimeout;
    int ImageStatus;
    CallBackFunc AcqImageCallBack;
    void * CallBackParameters;
    }strImageAcq;

  10. #10
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Structure Conversion between VB6 and C

    If you're using Milks's version you have to define 'timeout' and set the appropriate values in that structure.
    Code:
    Type timeval
       tv_sec As Long 'seconds(long)
       tv_usec As Long 'any micro seconds(long)
    End Type
    
    Type strImageAcq
       theHandle As Long
       ImageBufPtr As Long
       ImageBufSizePtr As Long
       TimeoutPtr As Long
       ImageStatus As Long
       AcqImageCallBack As Long
       CallBackParametersPtr As Long
    End Type
    
    Dim timeout As timeval
    
    Dim myImageAcq As strImageAcq
    timeout.tv_sec = 'whatever
    timeout.tv_usec = 'whatever
    
    
    myImageAcq.theHandle = theHandle
    myImageAcq.ImageBufPtr = VarPtr(theImageBuf(0))
    myImageAcq.ImageBufSizePtr = VarPtr(theImageBufSize)
    myImageAcq.TimeoutPtr = VarPtr(timeout)
    myImageAcq.ImageStatus = -1
    myImageAcq.AcqImageCallBack = 0 'or AddressOf callback function
    myImageAcq.CallBackParametersPtr = 0 'or VarPtr(callBackParams)

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    Sep 2012
    Posts
    433

    Re: Structure Conversion between VB6 and C

    Yes I did set timeout.tv_sec and timeout.tv_usec but result is the same.

  12. #12
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Structure Conversion between VB6 and C

    How about showing us the code you are using.

    If you wrap the code in [code]code goes here[/code] tags it is easier for us to read.
    W o t . S i g

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