-
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.
-
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.
-
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.
-
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.
>
>
-
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.
>
>
-
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.
-
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.
-
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>
-
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
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|