Using Win32 API Calls That Spawn Threads???


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 9 of 9

Thread: Using Win32 API Calls That Spawn Threads???

Hybrid View

  1. #1
    Steve Sokol Guest

    Using Win32 API Calls That Spawn Threads???


    I am trying to use a 3rd party API that interacts with the hardware drivers
    for a telephony "voice board" (a device similar to a voice modem). The API
    allows me to pass the address of a callback function to receive notification
    of hardware events (ringing, hangup, etc.)

    Unfortunately, the 3rd party API creates a worker thread that does the actual
    hardware monitoring and, when an event occurs, calls the callback function.
    This violates COM threading rules and yields an unstable application. Specifically
    the callback function cannot make any complex function calls, reference any
    COM object, any VB global object, or any function in an outside library accessed
    via a declare statement.

    I have tried having the 3rd party DLL call back to a C++ DLL that I wrote,
    which in-turn calls back to the VB function. Unfortunately the call is still
    in the context of the worker thread and not in the context of the VB thread,
    so again sparks fly.

    I have tried having the callback set a timer that in turn calls the VB callback
    (or have the callback set a timer that calls another function within the
    VB app) neither of which work. In both cases the SetTimer function (written
    in my C++ DLL and accessed via a type library) appears to work properly (returns
    a timer handle) but the timer never fires (or it never fires on my VB thread???).

    I realize that the "proper" way to do this is to handle the callback as a
    COM appartment and use the COM inter-thread marshalling (proxy/stub) techniques
    to call the function on it's proper thread. However, since the worker thread
    is created by the 3rd party API and not directly by me, I don't see how this
    can be done. (And honestly, without a good example I don't think I have
    the C++ skills to do this.)

    Any suggestions would be greatly appreciated.

    Steven Sokol

    P.S. Please remove the 'nospam' from my email address if you wish to email
    me directly. Thanks - S.

  2. #2
    Michael Shutt Guest

    Re: Using Win32 API Calls That Spawn Threads???

    This issue also comes up when writing a multi-threaded component in C++ (one
    that spawns a worker thread) for use by VB. The solution that MS recommends
    is to post window messages from the worker thread back to a hidden window in
    the main thread (the one created by VB), which in turn raises the
    appropriate COM event back to VB. This gets you around the marshalling and
    is preferred to marshalling since OLE/COM does essentially the same thing
    but less efficiently.

    So, I think you could solve the problem by using your C++ dll. Have the
    callback function for the 3rd party component in your C++ dll and simply
    post windows messages from it. You could post directly to VB, or to another
    C++ component that is running the same thread as VB which in turn raises COM
    events back to VB.

    Hope that makes sense.

    --
    Michael Shutt

    Please respond to newsgroup as I will not return direct emails.

    "Steve Sokol" <ssokol@.sokol-associates.nospam.com> wrote in message
    news:3ad60ed5$1@news.devx.com...
    >
    > I am trying to use a 3rd party API that interacts with the hardware

    drivers
    > for a telephony "voice board" (a device similar to a voice modem). The

    API
    > allows me to pass the address of a callback function to receive

    notification
    > of hardware events (ringing, hangup, etc.)
    >
    > Unfortunately, the 3rd party API creates a worker thread that does the

    actual
    > hardware monitoring and, when an event occurs, calls the callback

    function.
    > This violates COM threading rules and yields an unstable application.

    Specifically
    > the callback function cannot make any complex function calls, reference

    any
    > COM object, any VB global object, or any function in an outside library

    accessed
    > via a declare statement.
    >
    > I have tried having the 3rd party DLL call back to a C++ DLL that I wrote,
    > which in-turn calls back to the VB function. Unfortunately the call is

    still
    > in the context of the worker thread and not in the context of the VB

    thread,
    > so again sparks fly.
    >
    > I have tried having the callback set a timer that in turn calls the VB

    callback
    > (or have the callback set a timer that calls another function within the
    > VB app) neither of which work. In both cases the SetTimer function

    (written
    > in my C++ DLL and accessed via a type library) appears to work properly

    (returns
    > a timer handle) but the timer never fires (or it never fires on my VB

    thread???).
    >
    > I realize that the "proper" way to do this is to handle the callback as a
    > COM appartment and use the COM inter-thread marshalling (proxy/stub)

    techniques
    > to call the function on it's proper thread. However, since the worker

    thread
    > is created by the 3rd party API and not directly by me, I don't see how

    this
    > can be done. (And honestly, without a good example I don't think I have
    > the C++ skills to do this.)
    >
    > Any suggestions would be greatly appreciated.
    >
    > Steven Sokol
    >
    > P.S. Please remove the 'nospam' from my email address if you wish to

    email
    > me directly. Thanks - S.




  3. #3
    Steve Sokol Guest

    Re: Using Win32 API Calls That Spawn Threads???


    Thanks for the prompt reply! I would really like to implement a different
    structure -- right now I am using a polling architecture. Because of the
    timer limitation inherent with Windows I doubt I can scale the solution as
    far as I would like.

    I had thought about using a Windows Message structure but I have one small
    problem. My VB project is an ActiveX DLL that has no "visual" components
    and thus has no window to which I can post messages.

    I think I know what the answer is -- create a hidden window using CreateWindowEx,
    then hook the WindowProc to catch my WM_USER message that gets posted from
    the worker thread. Is this going to cause a problem? Will the extra window
    pose any problems to the main application's WindowProc or have any other
    negative impacts? Is there any way to have a message hook without having
    a window?

    Thanks in advance!

    Steven Sokol

    "Michael Shutt" <mshutt@mediaone.net> wrote:
    >This issue also comes up when writing a multi-threaded component in C++

    (one
    >that spawns a worker thread) for use by VB. The solution that MS recommends
    >is to post window messages from the worker thread back to a hidden window

    in
    >the main thread (the one created by VB), which in turn raises the
    >appropriate COM event back to VB. This gets you around the marshalling

    and
    >is preferred to marshalling since OLE/COM does essentially the same thing
    >but less efficiently.
    >
    >So, I think you could solve the problem by using your C++ dll. Have the
    >callback function for the 3rd party component in your C++ dll and simply
    >post windows messages from it. You could post directly to VB, or to another
    >C++ component that is running the same thread as VB which in turn raises

    COM
    >events back to VB.
    >
    >Hope that makes sense.
    >
    >--
    >Michael Shutt
    >
    >Please respond to newsgroup as I will not return direct emails.
    >
    >"Steve Sokol" <ssokol@.sokol-associates.nospam.com> wrote in message
    >news:3ad60ed5$1@news.devx.com...
    >>
    >> I am trying to use a 3rd party API that interacts with the hardware

    >drivers
    >> for a telephony "voice board" (a device similar to a voice modem). The

    >API
    >> allows me to pass the address of a callback function to receive

    >notification
    >> of hardware events (ringing, hangup, etc.)
    >>
    >> Unfortunately, the 3rd party API creates a worker thread that does the

    >actual
    >> hardware monitoring and, when an event occurs, calls the callback

    >function.
    >> This violates COM threading rules and yields an unstable application.

    >Specifically
    >> the callback function cannot make any complex function calls, reference

    >any
    >> COM object, any VB global object, or any function in an outside library

    >accessed
    >> via a declare statement.
    >>
    >> I have tried having the 3rd party DLL call back to a C++ DLL that I wrote,
    >> which in-turn calls back to the VB function. Unfortunately the call is

    >still
    >> in the context of the worker thread and not in the context of the VB

    >thread,
    >> so again sparks fly.
    >>
    >> I have tried having the callback set a timer that in turn calls the VB

    >callback
    >> (or have the callback set a timer that calls another function within the
    >> VB app) neither of which work. In both cases the SetTimer function

    >(written
    >> in my C++ DLL and accessed via a type library) appears to work properly

    >(returns
    >> a timer handle) but the timer never fires (or it never fires on my VB

    >thread???).
    >>
    >> I realize that the "proper" way to do this is to handle the callback as

    a
    >> COM appartment and use the COM inter-thread marshalling (proxy/stub)

    >techniques
    >> to call the function on it's proper thread. However, since the worker

    >thread
    >> is created by the 3rd party API and not directly by me, I don't see how

    >this
    >> can be done. (And honestly, without a good example I don't think I have
    >> the C++ skills to do this.)
    >>
    >> Any suggestions would be greatly appreciated.
    >>
    >> Steven Sokol
    >>
    >> P.S. Please remove the 'nospam' from my email address if you wish to

    >email
    >> me directly. Thanks - S.

    >
    >



  4. #4
    Peter Young Guest

    Re: Using Win32 API Calls That Spawn Threads???

    > Unfortunately, the 3rd party API creates a worker thread that does the actual
    > hardware monitoring and, when an event occurs, calls the callback function.
    > This violates COM threading rules and yields an unstable application. Specifically
    > the callback function cannot make any complex function calls, reference any
    > COM object, any VB global object, or any function in an outside library accessed
    > via a declare statement.


    I believe your VB callback function cannot execute any real VB code until you create an
    object on that thread. Matt Curland's Advanced Visual Basic 6 book details a technique for
    doing this.




  5. #5
    Michael Shutt Guest

    Re: Using Win32 API Calls That Spawn Threads???

    I think the CreateWindowEx approach should work just fine, but I haven't
    ever done it myself so I'm not sure. On the other hand, I don't see a
    problem with including a form in your dll project and using it has your
    hidden window.

    --
    Michael Shutt

    Please respond to newsgroup as I will not return direct emails.

    "Steve Sokol" <ssokol@.sokol-associates.nospam.com> wrote in message
    news:3ad65aba$1@news.devx.com...
    >
    > Thanks for the prompt reply! I would really like to implement a different
    > structure -- right now I am using a polling architecture. Because of the
    > timer limitation inherent with Windows I doubt I can scale the solution as
    > far as I would like.
    >
    > I had thought about using a Windows Message structure but I have one small
    > problem. My VB project is an ActiveX DLL that has no "visual" components
    > and thus has no window to which I can post messages.
    >
    > I think I know what the answer is -- create a hidden window using

    CreateWindowEx,
    > then hook the WindowProc to catch my WM_USER message that gets posted from
    > the worker thread. Is this going to cause a problem? Will the extra

    window
    > pose any problems to the main application's WindowProc or have any other
    > negative impacts? Is there any way to have a message hook without having
    > a window?
    >
    > Thanks in advance!
    >
    > Steven Sokol
    >

    <snip>



  6. #6
    Michael Shutt Guest

    Re: Using Win32 API Calls That Spawn Threads???

    This issue also comes up when writing a multi-threaded component in C++ (one
    that spawns a worker thread) for use by VB. The solution that MS recommends
    is to post window messages from the worker thread back to a hidden window in
    the main thread (the one created by VB), which in turn raises the
    appropriate COM event back to VB. This gets you around the marshalling and
    is preferred to marshalling since OLE/COM does essentially the same thing
    but less efficiently.

    So, I think you could solve the problem by using your C++ dll. Have the
    callback function for the 3rd party component in your C++ dll and simply
    post windows messages from it. You could post directly to VB, or to another
    C++ component that is running the same thread as VB which in turn raises COM
    events back to VB.

    Hope that makes sense.

    --
    Michael Shutt

    Please respond to newsgroup as I will not return direct emails.

    "Steve Sokol" <ssokol@.sokol-associates.nospam.com> wrote in message
    news:3ad60ed5$1@news.devx.com...
    >
    > I am trying to use a 3rd party API that interacts with the hardware

    drivers
    > for a telephony "voice board" (a device similar to a voice modem). The

    API
    > allows me to pass the address of a callback function to receive

    notification
    > of hardware events (ringing, hangup, etc.)
    >
    > Unfortunately, the 3rd party API creates a worker thread that does the

    actual
    > hardware monitoring and, when an event occurs, calls the callback

    function.
    > This violates COM threading rules and yields an unstable application.

    Specifically
    > the callback function cannot make any complex function calls, reference

    any
    > COM object, any VB global object, or any function in an outside library

    accessed
    > via a declare statement.
    >
    > I have tried having the 3rd party DLL call back to a C++ DLL that I wrote,
    > which in-turn calls back to the VB function. Unfortunately the call is

    still
    > in the context of the worker thread and not in the context of the VB

    thread,
    > so again sparks fly.
    >
    > I have tried having the callback set a timer that in turn calls the VB

    callback
    > (or have the callback set a timer that calls another function within the
    > VB app) neither of which work. In both cases the SetTimer function

    (written
    > in my C++ DLL and accessed via a type library) appears to work properly

    (returns
    > a timer handle) but the timer never fires (or it never fires on my VB

    thread???).
    >
    > I realize that the "proper" way to do this is to handle the callback as a
    > COM appartment and use the COM inter-thread marshalling (proxy/stub)

    techniques
    > to call the function on it's proper thread. However, since the worker

    thread
    > is created by the 3rd party API and not directly by me, I don't see how

    this
    > can be done. (And honestly, without a good example I don't think I have
    > the C++ skills to do this.)
    >
    > Any suggestions would be greatly appreciated.
    >
    > Steven Sokol
    >
    > P.S. Please remove the 'nospam' from my email address if you wish to

    email
    > me directly. Thanks - S.




  7. #7
    Steve Sokol Guest

    Re: Using Win32 API Calls That Spawn Threads???


    Thanks for the prompt reply! I would really like to implement a different
    structure -- right now I am using a polling architecture. Because of the
    timer limitation inherent with Windows I doubt I can scale the solution as
    far as I would like.

    I had thought about using a Windows Message structure but I have one small
    problem. My VB project is an ActiveX DLL that has no "visual" components
    and thus has no window to which I can post messages.

    I think I know what the answer is -- create a hidden window using CreateWindowEx,
    then hook the WindowProc to catch my WM_USER message that gets posted from
    the worker thread. Is this going to cause a problem? Will the extra window
    pose any problems to the main application's WindowProc or have any other
    negative impacts? Is there any way to have a message hook without having
    a window?

    Thanks in advance!

    Steven Sokol

    "Michael Shutt" <mshutt@mediaone.net> wrote:
    >This issue also comes up when writing a multi-threaded component in C++

    (one
    >that spawns a worker thread) for use by VB. The solution that MS recommends
    >is to post window messages from the worker thread back to a hidden window

    in
    >the main thread (the one created by VB), which in turn raises the
    >appropriate COM event back to VB. This gets you around the marshalling

    and
    >is preferred to marshalling since OLE/COM does essentially the same thing
    >but less efficiently.
    >
    >So, I think you could solve the problem by using your C++ dll. Have the
    >callback function for the 3rd party component in your C++ dll and simply
    >post windows messages from it. You could post directly to VB, or to another
    >C++ component that is running the same thread as VB which in turn raises

    COM
    >events back to VB.
    >
    >Hope that makes sense.
    >
    >--
    >Michael Shutt
    >
    >Please respond to newsgroup as I will not return direct emails.
    >
    >"Steve Sokol" <ssokol@.sokol-associates.nospam.com> wrote in message
    >news:3ad60ed5$1@news.devx.com...
    >>
    >> I am trying to use a 3rd party API that interacts with the hardware

    >drivers
    >> for a telephony "voice board" (a device similar to a voice modem). The

    >API
    >> allows me to pass the address of a callback function to receive

    >notification
    >> of hardware events (ringing, hangup, etc.)
    >>
    >> Unfortunately, the 3rd party API creates a worker thread that does the

    >actual
    >> hardware monitoring and, when an event occurs, calls the callback

    >function.
    >> This violates COM threading rules and yields an unstable application.

    >Specifically
    >> the callback function cannot make any complex function calls, reference

    >any
    >> COM object, any VB global object, or any function in an outside library

    >accessed
    >> via a declare statement.
    >>
    >> I have tried having the 3rd party DLL call back to a C++ DLL that I wrote,
    >> which in-turn calls back to the VB function. Unfortunately the call is

    >still
    >> in the context of the worker thread and not in the context of the VB

    >thread,
    >> so again sparks fly.
    >>
    >> I have tried having the callback set a timer that in turn calls the VB

    >callback
    >> (or have the callback set a timer that calls another function within the
    >> VB app) neither of which work. In both cases the SetTimer function

    >(written
    >> in my C++ DLL and accessed via a type library) appears to work properly

    >(returns
    >> a timer handle) but the timer never fires (or it never fires on my VB

    >thread???).
    >>
    >> I realize that the "proper" way to do this is to handle the callback as

    a
    >> COM appartment and use the COM inter-thread marshalling (proxy/stub)

    >techniques
    >> to call the function on it's proper thread. However, since the worker

    >thread
    >> is created by the 3rd party API and not directly by me, I don't see how

    >this
    >> can be done. (And honestly, without a good example I don't think I have
    >> the C++ skills to do this.)
    >>
    >> Any suggestions would be greatly appreciated.
    >>
    >> Steven Sokol
    >>
    >> P.S. Please remove the 'nospam' from my email address if you wish to

    >email
    >> me directly. Thanks - S.

    >
    >



  8. #8
    Peter Young Guest

    Re: Using Win32 API Calls That Spawn Threads???

    > Unfortunately, the 3rd party API creates a worker thread that does the actual
    > hardware monitoring and, when an event occurs, calls the callback function.
    > This violates COM threading rules and yields an unstable application. Specifically
    > the callback function cannot make any complex function calls, reference any
    > COM object, any VB global object, or any function in an outside library accessed
    > via a declare statement.


    I believe your VB callback function cannot execute any real VB code until you create an
    object on that thread. Matt Curland's Advanced Visual Basic 6 book details a technique for
    doing this.




  9. #9
    Michael Shutt Guest

    Re: Using Win32 API Calls That Spawn Threads???

    I think the CreateWindowEx approach should work just fine, but I haven't
    ever done it myself so I'm not sure. On the other hand, I don't see a
    problem with including a form in your dll project and using it has your
    hidden window.

    --
    Michael Shutt

    Please respond to newsgroup as I will not return direct emails.

    "Steve Sokol" <ssokol@.sokol-associates.nospam.com> wrote in message
    news:3ad65aba$1@news.devx.com...
    >
    > Thanks for the prompt reply! I would really like to implement a different
    > structure -- right now I am using a polling architecture. Because of the
    > timer limitation inherent with Windows I doubt I can scale the solution as
    > far as I would like.
    >
    > I had thought about using a Windows Message structure but I have one small
    > problem. My VB project is an ActiveX DLL that has no "visual" components
    > and thus has no window to which I can post messages.
    >
    > I think I know what the answer is -- create a hidden window using

    CreateWindowEx,
    > then hook the WindowProc to catch my WM_USER message that gets posted from
    > the worker thread. Is this going to cause a problem? Will the extra

    window
    > pose any problems to the main application's WindowProc or have any other
    > negative impacts? Is there any way to have a message hook without having
    > a window?
    >
    > Thanks in advance!
    >
    > Steven Sokol
    >

    <snip>



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
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center