Results 1 to 14 of 14

Thread: How do I callback from C to VB?

  1. #1

    Thread Starter
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    How do I callback from C to VB?

    I am trying to do a callback from my C++ dll to a VB program
    I define the callback function pointer like so
    Code:
    typedef void ( __stdcall *PFNODSCALLBACK)(PSTR pszString);
    VB declares a function that exists in the dll and passes it the Addressof MyCallback as long
    The callback function is defined as:
    VB Code:
    1. Public Sub MyCallBack(ByVal lpDebug As Long)
    2.     Form1.logevent "Debug Output: " & Hex(lpDebug)
    3. End Sub
    later on in the dll it's called like this
    Code:
    //defined earlier
    PFNODSCALLBACK m_pfnODSCallback;
    //defined and initialized somewhere
    char szBuffer[ 1024 ];
    //call the VB callback function
    m_pfnODSCallback( szBuffer );
    Now, the callback is being made, but if I try to access the variable passed back I get a GPF.

    So, my question is, how do I pass variables to a VB callback routine?

  2. #2

    Thread Starter
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: How do I callback from C to VB?

    More info,

    The code as presented works as long as the VB program is run from the IDE, but crashes when I try to access the variable from a compiled exe.

    Also, the callback is being made from a new thread I created in the dll.

    As mentioned above, the callback works OK as long as I don't try to access the parameters passed to it.

    What Im' trying to do must be do-able since many API functions rely on callbacks and can be run from VB.

    Anyone have any examples of making a callback from C++ dll to VB 6?

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594

    Re: How do I callback from C to VB?

    I had, a long time ago.

    Is the callback sub in a global module?
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: How do I callback from C to VB?

    Yes, the VB callback routine is in a global module.

  5. #5

    Thread Starter
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: How do I callback from C to VB?

    OK, I've traced the problem to the fact that I'm making the callback from a different thread than the VB address was passed in. Since the call is still being made I know the address is still valid in the separate thread. So, the problem must be with the stack.??

  6. #6

    Thread Starter
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: How do I callback from C to VB?

    More troubleshooting:

    I found that what was causing my program to crash was the VB call to Hex.
    This is probably because MyCallBack is running in a different thread than my main VB program so has not been properly initialized (all that COM+ stuff)

    Is there some way that I can execute a function in a thread that is already running? Many API's which require callbacks must do it somehow.

  7. #7
    Hyperactive Member Maven's Avatar
    Join Date
    Feb 2003
    Location
    Greeneville, TN
    Posts
    322

    Re: How do I callback from C to VB?

    Quote Originally Posted by moeur
    More troubleshooting:

    I found that what was causing my program to crash was the VB call to Hex.
    This is probably because MyCallBack is running in a different thread than my main VB program so has not been properly initialized (all that COM+ stuff)

    Is there some way that I can execute a function in a thread that is already running? Many API's which require callbacks must do it somehow.
    Try changing you're callback routine to a function instead of a sub.
    Education is an admirable thing, but it is well to remember from time to time that nothing that is worth knowing can be taught. - Oscar Wilde

  8. #8

    Thread Starter
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: How do I callback from C to VB?

    Try changing you're callback routine to a function instead of a sub.
    OK, simple enough to try out...
    No, didn't work.

    I've been reading more about how VB treats threads. When VB creates threads, each thread acts as if it were an application of its own. Each thread gets its own copy of global variables, the Err object and the App object. The information for the location of these objects is stored in each thread's thread local storage (TLS).

    So when I create my own thread, VB has no knowledge of the thread, if I encounter an error for example, VB trys to access the Err object, but instead gets an access violation because I haven't properly set up the TLS.

    I came across some code where someone had discovered that the required address in TLS was in slot #4. So I tried the following
    Before creating the new thread, get the address from TLS
    Code:
    LPVOID ThreadInfo = TlsGetValue(4);
    Pass this value as the parameter to the ThreadProc when the thread is created.
    Inside the threadProc I can put this value in my TLS.
    Code:
    TlsSetValue(4, lParam);
    And tell VB I'm in a single thread Apartment
    Code:
    CoInitialize(0);
    Unfortunately this didn't solve any problems.

  9. #9
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594

    Re: How do I callback from C to VB?

    So I guess your problems might get solved if you left threading out completely.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  10. #10

    Thread Starter
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: How do I callback from C to VB?

    So I guess your problems might get solved if you left threading out completely
    Then I would be admitting that I've been beaten. Actually I'm about ready to do that.

    According to Curland's book, I need to
    CoInitialize(0);
    CoCreateInstance (...);
    before making the callback.
    By Creating the instance I will be populating my TLS
    Problem is, I don't know how to get a valid CLSID to use
    I can get it from ProgId, but I don't know how to get that either.

  11. #11
    Fanatic Member
    Join Date
    Dec 2003
    Posts
    703

    Re: How do I callback from C to VB?

    From the book it looks like you just have to create *some* object in the thread to initialises the TLS slots. So you can just create some dummy COM class and create an object of it. Or just create an object of any other already-defined COM class. You can look up CLSIDs in the registry, or use a tool to do it for you.

    I might be wrong with some of that, my COM and VB are hazy nowadays.
    an ending

  12. #12
    Hyperactive Member Maven's Avatar
    Join Date
    Feb 2003
    Location
    Greeneville, TN
    Posts
    322

    Re: How do I callback from C to VB?

    Quote Originally Posted by moeur
    OK, simple enough to try out...
    No, didn't work.

    I've been reading more about how VB treats threads. When VB creates threads, each thread acts as if it were an application of its own. Each thread gets its own copy of global variables, the Err object and the App object. The information for the location of these objects is stored in each thread's thread local storage (TLS).

    So when I create my own thread, VB has no knowledge of the thread, if I encounter an error for example, VB trys to access the Err object, but instead gets an access violation because I haven't properly set up the TLS.

    I came across some code where someone had discovered that the required address in TLS was in slot #4. So I tried the following
    Before creating the new thread, get the address from TLS
    Code:
    LPVOID ThreadInfo = TlsGetValue(4);
    Pass this value as the parameter to the ThreadProc when the thread is created.
    Inside the threadProc I can put this value in my TLS.
    Code:
    TlsSetValue(4, lParam);
    And tell VB I'm in a single thread Apartment
    Code:
    CoInitialize(0);
    Unfortunately this didn't solve any problems.
    I had done this when I was in my little mix asm with vb mood. I just cannot remember what it was, see I had a little hicup as well. It had something to do with how I was calling the damn thing and I cannot remember for the life of me what it was. Try looking it up on msdn because that is likely where I found a solution.
    Education is an admirable thing, but it is well to remember from time to time that nothing that is worth knowing can be taught. - Oscar Wilde

  13. #13

    Thread Starter
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: How do I callback from C to VB?

    From the book it looks like you just have to create *some* object in the thread to initialises the TLS slots. So you can just create some dummy COM class and create an object of it. Or just create an object of any other already-defined COM class.
    OK, I tried this
    Code:
      DEFINE_GUID(CLSID_ListBox,0x58DA8D8AL,0x9D6A,0x101B,0xAF,0xC0,0x42,0x10,0x10,0x2A,0x8D,0xA7);
      
      // Call CoInitialize to initialize the COM library
      hr = CoInitialize(NULL);
      //Then create an instance of some Com object
      if (SUCCEEDED(hr))
      {
        hr = CoCreateInstance(CLSID_ListBox,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IUnknown,
                              (void **) &pITS);
        if (FAILED(hr))
        {
          CoUninitialize();
          return hr;
        }
       //make the call
        if (DataReadNotify != NULL) DataReadNotify((long)hr);
    No luck. I tried several different CLSIDs.
    I think it's time to throw in the towel.

  14. #14
    Lively Member
    Join Date
    May 2004
    Location
    Home
    Posts
    85

    Re: How do I callback from C to VB?

    So is the conclusion here that it is not possible to create a win32 dll in VB6 even with all these attempted work arounds?

    I would love to experiment with hooks inside dlls that I could make in VB, but it seems that this is one tricky case.
    What is the current problem here... COM Enabling of a thread?

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