 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Peter Guest
|
Posted: Mon Jun 14, 2004 9:35 pm Post subject: How can I change the threading model of an already existing |
|
|
How can I change the threading model of an already existing interface ?
I know it can't be done from the ATL tab of the project properties. The
option there seems pritty useless.
Some time ago I made an activeX dll with COM interface (without really
knowing much about COM).
I chose "single" as threading model when creating the COM object.
The person who needs to use the dll works under the .NET environment (vb).
rrrrr ... I have tried to debug small test apps using the dll but .net is
not for me ;-)
Following problem is something I have NOT been able to solve yet.
The dll class is instanciated in a new thread (in the .NET app) and once the
first function is called an exception occurs :
"An unhandled exception of type 'System.InvalidCastException' occurred in
*.exe"
"Additional information: QueryInterface for interface dll.class failed."
I have been searching the newsgroups and all I can find is references to the
app and com object not using the same threading model ?
(e.g.
[url]http://groups.google.be/groups?hl=nl&lr=&ie=UTF-8&threadm=78b36382.0210021252.52ba8a0%40posting.google.com&rnum=1&prev=/groups%3Fhl%3Dnl%26lr%3D%26ie%3DUTF-8%26q%3DI%27m%2Btrying%2Bto%2Bcreate%2Ba%2Bweb%2Bservice%2Bout%2Bof%2Ban%2Bexisting%2B(ATL%2BC%252B%252B)%2BCOM[/url] )
One other bit of information. In the ATL tab of the project properties I
use :
Instancing : "Single Use" and OLE init... "APARTMENTTHREADED"
So how can I resolve this issue ?
1. According to the link : "Register a proxy and stub for the interface. The
easiest way to do this
is to register the type library that defines the interface." like the MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
2. Change the threading model of the interface ? To STA maybe ?
But how ?
3. I noticed that in .NET (from .NET help) the thread could possibly be set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the person
who uses the dll creates such threads STA as well. Could that be the
solution ?
I'm out of ideas and I NEED to get this to work soon.
The code I put in the COM object (co)class is single threaded, hence me
chosing "single" when I created the COM object.
But I guess, because I use "Single use" in the Instancing property STA is
safe as well ??
Any other help is appreciated.
|
|
| Back to top |
|
 |
Jean-Marie Babet Guest
|
Posted: Mon Jun 14, 2004 9:59 pm Post subject: Re: How can I change the threading model of an already exist |
|
|
Hello,
| Quote: | How can I change the threading model of an already existing interface ?
I know it can't be done from the ATL tab of the project properties. The
option there seems pritty useless.
|
While there's no button to change the threading model of a COM object, the
change can be applied manually. If you look in the cbuilder6objrepos
directory you'll see the templates files used by the COM Object Wizards:
comobject.h and comobject.cpp. In these files you'll see sections that look
as follows:
[!if=(ThreadingModel, "Single")]
#define ATL_APARTMENT_THREADED
[!endif]
[!if=(ThreadingModel, "Apartment")]
#define ATL_APARTMENT_THREADED
[!endif]
[!if=(ThreadingModel, "Both")]
#define ATL_FREE_THREADED
[!endif]
[!if=(ThreadingModel, "Free")]
#define ATL_FREE_THREADED
[!endif]
[!if=(ThreadingModel, "Neutral")]
#define ATL_APARTMENT_THREADED
[!endif]
Basically, the Wizard preprocesses these template files using key/value
pairs from a Property Bag. As you can probably guess, if you picked
"Apartment", then the Wizard generates:
#define ATL_APARTMENT_THREADED
etc.. etc..
So if you search for the lines that read:
[!if=(ThreadingModel, "xxxx")]
.... Here is the code to be emitted ...
[!endif]
You'll find the code that dependent on the ThreadModel and you can switch
after you've already generated an Object.
| Quote: | 1. According to the link : "Register a proxy and stub for the interface.
The
easiest way to do this
is to register the type library that defines the interface." like the MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
|
TypeLibrary marshalling is basically an easy way to avoid having to write
proxy/stub but I thought (I might be wrong here since I've been away from
COM for a while) that it's only applicable for automation types. Anyway. to
make sure you're typelibrary is registered, see the
HKCRTypeLib{XXX....XXX} key where XXXX is the GUID of the TypeLibrary [you
can see that in the TypeLibrary Editor or in the _TLB.h files generated].
| Quote: | 3. I noticed that in .NET (from .NET help) the thread could possibly be
set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the person
who uses the dll creates such threads STA as well. Could that be the
solution ?
|
That's a solution but you're relying on having control on the Client side
usage of your object.... ????
Regards,
Bruneau.
"Peter" <Peter (AT) Smart-Projects (DOT) net> wrote
| Quote: | How can I change the threading model of an already existing interface ?
I know it can't be done from the ATL tab of the project properties. The
option there seems pritty useless.
Some time ago I made an activeX dll with COM interface (without really
knowing much about COM).
I chose "single" as threading model when creating the COM object.
The person who needs to use the dll works under the .NET environment (vb).
rrrrr ... I have tried to debug small test apps using the dll but .net is
not for me ;-)
Following problem is something I have NOT been able to solve yet.
The dll class is instanciated in a new thread (in the .NET app) and once
the
first function is called an exception occurs :
"An unhandled exception of type 'System.InvalidCastException' occurred in
*.exe"
"Additional information: QueryInterface for interface dll.class failed."
I have been searching the newsgroups and all I can find is references to
the
app and com object not using the same threading model ?
(e.g.
http://groups.google.be/groups?hl=nl&lr=&ie=UTF-8&threadm=78b36382.0210021252.52ba8a0%40posting.google.com&rnum=1&prev=/groups%3Fhl%3Dnl%26lr%3D%26ie%3D |
UTF-8%26q%3DI%27m%2Btrying%2Bto%2Bcreate%2Ba%2Bweb%2Bservice%2Bout%2Bof%2Ban
%2Bexisting%2B(ATL%2BC%252B%252B)%2BCOM )
| Quote: |
One other bit of information. In the ATL tab of the project properties I
use :
Instancing : "Single Use" and OLE init... "APARTMENTTHREADED"
So how can I resolve this issue ?
1. According to the link : "Register a proxy and stub for the interface.
The
easiest way to do this
is to register the type library that defines the interface." like the MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
2. Change the threading model of the interface ? To STA maybe ?
But how ?
3. I noticed that in .NET (from .NET help) the thread could possibly be
set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the person
who uses the dll creates such threads STA as well. Could that be the
solution ?
I'm out of ideas and I NEED to get this to work soon.
The code I put in the COM object (co)class is single threaded, hence me
chosing "single" when I created the COM object.
But I guess, because I use "Single use" in the Instancing property STA is
safe as well ??
Any other help is appreciated.
|
|
|
| Back to top |
|
 |
Peter Guest
|
Posted: Mon Jun 14, 2004 10:48 pm Post subject: Re: How can I change the threading model of an already exist |
|
|
I'm not sure I understand your explanation ?
Btw. I use Borland c++ Builder 5
Do I have to change a #define somewhere ??
When I open the coclass files (h and cpp) for instance, where I added the
code,
I can see for instance :
class ATL_NO_VTABLE TCDDVDIOImpl :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<TCDDVDIOImpl, &CLSID_CDDVDIO>,
public ICDDVDIO
So will "CComSingleThreadModel" this be replaced then or .. what ?
| Quote: |
While there's no button to change the threading model of a COM object, the
change can be applied manually. If you look in the cbuilder6objrepos
directory you'll see the templates files used by the COM Object Wizards:
comobject.h and comobject.cpp. In these files you'll see sections that
look
as follows:
[!if=(ThreadingModel, "Single")]
#define ATL_APARTMENT_THREADED
[!endif]
[!if=(ThreadingModel, "Apartment")]
#define ATL_APARTMENT_THREADED
[!endif]
[!if=(ThreadingModel, "Both")]
#define ATL_FREE_THREADED
[!endif]
[!if=(ThreadingModel, "Free")]
#define ATL_FREE_THREADED
[!endif]
[!if=(ThreadingModel, "Neutral")]
#define ATL_APARTMENT_THREADED
[!endif]
Basically, the Wizard preprocesses these template files using key/value
pairs from a Property Bag. As you can probably guess, if you picked
"Apartment", then the Wizard generates:
#define ATL_APARTMENT_THREADED
etc.. etc..
So if you search for the lines that read:
[!if=(ThreadingModel, "xxxx")]
.... Here is the code to be emitted ...
[!endif]
You'll find the code that dependent on the ThreadModel and you can switch
after you've already generated an Object.
1. According to the link : "Register a proxy and stub for the interface.
The
easiest way to do this
is to register the type library that defines the interface." like the MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
TypeLibrary marshalling is basically an easy way to avoid having to write
proxy/stub but I thought (I might be wrong here since I've been away from
COM for a while) that it's only applicable for automation types. Anyway.
to
make sure you're typelibrary is registered, see the
HKCRTypeLib{XXX....XXX} key where XXXX is the GUID of the TypeLibrary
[you
can see that in the TypeLibrary Editor or in the _TLB.h files generated].
3. I noticed that in .NET (from .NET help) the thread could possibly be
set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the
person
who uses the dll creates such threads STA as well. Could that be the
solution ?
That's a solution but you're relying on having control on the Client side
usage of your object.... ????
Regards,
Bruneau.
"Peter" <Peter (AT) Smart-Projects (DOT) net> wrote in message
news:40ce19f1$1 (AT) newsgroups (DOT) borland.com...
How can I change the threading model of an already existing interface ?
I know it can't be done from the ATL tab of the project properties. The
option there seems pritty useless.
Some time ago I made an activeX dll with COM interface (without really
knowing much about COM).
I chose "single" as threading model when creating the COM object.
The person who needs to use the dll works under the .NET environment
(vb).
rrrrr ... I have tried to debug small test apps using the dll but .net
is
not for me ;-)
Following problem is something I have NOT been able to solve yet.
The dll class is instanciated in a new thread (in the .NET app) and once
the
first function is called an exception occurs :
"An unhandled exception of type 'System.InvalidCastException' occurred
in
*.exe"
"Additional information: QueryInterface for interface dll.class failed."
I have been searching the newsgroups and all I can find is references to
the
app and com object not using the same threading model ?
(e.g.
http://groups.google.be/groups?hl=nl&lr=&ie=UTF-8&threadm=78b36382.0210021252.52ba8a0%40posting.google.com&rnum=1&prev=/groups%3Fhl%3Dnl%26lr%3D%26ie%3D
UTF-8%26q%3DI%27m%2Btrying%2Bto%2Bcreate%2Ba%2Bweb%2Bservice%2Bout%2Bof%2Ban
%2Bexisting%2B(ATL%2BC%252B%252B)%2BCOM )
One other bit of information. In the ATL tab of the project properties
I
use :
Instancing : "Single Use" and OLE init... "APARTMENTTHREADED"
So how can I resolve this issue ?
1. According to the link : "Register a proxy and stub for the interface.
The
easiest way to do this
is to register the type library that defines the interface." like the MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
2. Change the threading model of the interface ? To STA maybe ?
But how ?
3. I noticed that in .NET (from .NET help) the thread could possibly be
set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the
person
who uses the dll creates such threads STA as well. Could that be the
solution ?
I'm out of ideas and I NEED to get this to work soon.
The code I put in the COM object (co)class is single threaded, hence me
chosing "single" when I created the COM object.
But I guess, because I use "Single use" in the Instancing property STA
is
safe as well ??
Any other help is appreciated.
|
|
|
| Back to top |
|
 |
Peter Guest
|
Posted: Mon Jun 14, 2004 10:52 pm Post subject: Re: How can I change the threading model of an already exist |
|
|
What do you mean with automation types ?
| Quote: |
TypeLibrary marshalling is basically an easy way to avoid having to write
proxy/stub but I thought (I might be wrong here since I've been away from
COM for a while) that it's only applicable for automation types. Anyway.
to
make sure you're typelibrary is registered, see the
HKCRTypeLib{XXX....XXX} key where XXXX is the GUID of the TypeLibrary
[you
can see that in the TypeLibrary Editor or in the _TLB.h files generated].
|
|
|
| Back to top |
|
 |
Jean-Marie Babet Guest
|
Posted: Mon Jun 14, 2004 11:40 pm Post subject: Re: How can I change the threading model of an already exist |
|
|
Hello,
| Quote: | So will "CComSingleThreadModel" this be replaced then or .. what ?
|
Yes! For example, you can find the following in the template file:
////////////////////////////////////////////////////////////////////////////
/
class ATL_NO_VTABLE [!ClassName] :
[!if=(ThreadingModel, "Single")]
public CComObjectRootEx<CComSingleThreadModel>,
[!endif]
[!if=(ThreadingModel, "Apartment")]
public CComObjectRootEx<CComSingleThreadModel>,
[!endif]
[!if=(ThreadingModel, "Both")]
public CComObjectRootEx<CComMultiThreadModel>,
[!endif]
[!if=(ThreadingModel, "Free")]
public CComObjectRootEx<CComMultiThreadModel>,
[!endif]
[!if=(ThreadingModel, "Neutral")]
public CComObjectRootEx<CComMultiThreadModel>,
[!endif]
So, if you wanted to switch from "Single" to "Free", you would change the
line in your header file that reads
public CComObjectRootEx<CComSingleThreadModel>,
to the following:
public CComObjectRootEx<CComMultiThreadModel>,
Another way to look at this is to create two new COM objects, preferably
named identically, in two separate projects; and then compare the generated
headers and sources. By picking one threading model in one and another
threading model in the other, you can see the difference in the code
generated.
What I want to bring up is the fact that with a little bit of tweaking you
can change the threading model of an object *after* you've generated the
code with the Wizard. We did not write a code manager for this because it's
rather rare that you switch the threading model.
Let me know if the above needs clarification.
Regards,
Bruneau.
"Peter" <Peter (AT) Smart-Projects (DOT) net> wrote
| Quote: | I'm not sure I understand your explanation ?
Btw. I use Borland c++ Builder 5
Do I have to change a #define somewhere ??
When I open the coclass files (h and cpp) for instance, where I added the
code,
I can see for instance :
class ATL_NO_VTABLE TCDDVDIOImpl :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<TCDDVDIOImpl, &CLSID_CDDVDIO>,
public ICDDVDIO
So will "CComSingleThreadModel" this be replaced then or .. what ?
While there's no button to change the threading model of a COM object,
the
change can be applied manually. If you look in the cbuilder6objrepos
directory you'll see the templates files used by the COM Object Wizards:
comobject.h and comobject.cpp. In these files you'll see sections that
look
as follows:
[!if=(ThreadingModel, "Single")]
#define ATL_APARTMENT_THREADED
[!endif]
[!if=(ThreadingModel, "Apartment")]
#define ATL_APARTMENT_THREADED
[!endif]
[!if=(ThreadingModel, "Both")]
#define ATL_FREE_THREADED
[!endif]
[!if=(ThreadingModel, "Free")]
#define ATL_FREE_THREADED
[!endif]
[!if=(ThreadingModel, "Neutral")]
#define ATL_APARTMENT_THREADED
[!endif]
Basically, the Wizard preprocesses these template files using key/value
pairs from a Property Bag. As you can probably guess, if you picked
"Apartment", then the Wizard generates:
#define ATL_APARTMENT_THREADED
etc.. etc..
So if you search for the lines that read:
[!if=(ThreadingModel, "xxxx")]
.... Here is the code to be emitted ...
[!endif]
You'll find the code that dependent on the ThreadModel and you can
switch
after you've already generated an Object.
1. According to the link : "Register a proxy and stub for the
interface.
The
easiest way to do this
is to register the type library that defines the interface." like the
MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
TypeLibrary marshalling is basically an easy way to avoid having to
write
proxy/stub but I thought (I might be wrong here since I've been away
from
COM for a while) that it's only applicable for automation types.
Anyway.
to
make sure you're typelibrary is registered, see the
HKCRTypeLib{XXX....XXX} key where XXXX is the GUID of the TypeLibrary
[you
can see that in the TypeLibrary Editor or in the _TLB.h files
generated].
3. I noticed that in .NET (from .NET help) the thread could possibly
be
set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the
person
who uses the dll creates such threads STA as well. Could that be the
solution ?
That's a solution but you're relying on having control on the Client
side
usage of your object.... ????
Regards,
Bruneau.
"Peter" <Peter (AT) Smart-Projects (DOT) net> wrote in message
news:40ce19f1$1 (AT) newsgroups (DOT) borland.com...
How can I change the threading model of an already existing interface
?
I know it can't be done from the ATL tab of the project properties.
The
option there seems pritty useless.
Some time ago I made an activeX dll with COM interface (without really
knowing much about COM).
I chose "single" as threading model when creating the COM object.
The person who needs to use the dll works under the .NET environment
(vb).
rrrrr ... I have tried to debug small test apps using the dll but .net
is
not for me ;-)
Following problem is something I have NOT been able to solve yet.
The dll class is instanciated in a new thread (in the .NET app) and
once
the
first function is called an exception occurs :
"An unhandled exception of type 'System.InvalidCastException' occurred
in
*.exe"
"Additional information: QueryInterface for interface dll.class
failed."
I have been searching the newsgroups and all I can find is references
to
the
app and com object not using the same threading model ?
(e.g.
http://groups.google.be/groups?hl=nl&lr=&ie=UTF-8&threadm=78b36382.0210021252.52ba8a0%40posting.google.com&rnum=1&prev=/groups%3Fhl%3Dnl%26lr%3D%26ie%3D
UTF-8%26q%3DI%27m%2Btrying%2Bto%2Bcreate%2Ba%2Bweb%2Bservice%2Bout%2Bof%2Ban
%2Bexisting%2B(ATL%2BC%252B%252B)%2BCOM )
One other bit of information. In the ATL tab of the project
properties
I
use :
Instancing : "Single Use" and OLE init... "APARTMENTTHREADED"
So how can I resolve this issue ?
1. According to the link : "Register a proxy and stub for the
interface.
The
easiest way to do this
is to register the type library that defines the interface." like the
MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
2. Change the threading model of the interface ? To STA maybe ?
But how ?
3. I noticed that in .NET (from .NET help) the thread could possibly
be
set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the
person
who uses the dll creates such threads STA as well. Could that be the
solution ?
I'm out of ideas and I NEED to get this to work soon.
The code I put in the COM object (co)class is single threaded, hence
me
chosing "single" when I created the COM object.
But I guess, because I use "Single use" in the Instancing property STA
is
safe as well ??
Any other help is appreciated.
|
|
|
| Back to top |
|
 |
Jean-Marie Babet Guest
|
Posted: Mon Jun 14, 2004 11:48 pm Post subject: Re: How can I change the threading model of an already exist |
|
|
Hello,
Automation types are types that are allowed as parameters in Automation
objects. For example, say I wanted to expose a method that takes a string; I
could make the parameter of type LPSTR or of type BSTR. LPSTR is not an
automation type while BSTR is. Likewise, if I wanted to expose an array
parameter, the Automation-type would be a SAFEARRAY whereas a plain array,
say char[] or char*, would not be an Automation type.
Basically, automation interfaces have a restricted list of types that they
can use. You can find more information at the following link:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap8_9a9a.asp
Regards,
Bruneau.
"Peter" <Peter (AT) Smart-Projects (DOT) net> wrote
| Quote: | What do you mean with automation types ?
TypeLibrary marshalling is basically an easy way to avoid having to
write
proxy/stub but I thought (I might be wrong here since I've been away
from
COM for a while) that it's only applicable for automation types.
Anyway.
to
make sure you're typelibrary is registered, see the
HKCRTypeLib{XXX....XXX} key where XXXX is the GUID of the TypeLibrary
[you
can see that in the TypeLibrary Editor or in the _TLB.h files
generated].
|
|
|
| Back to top |
|
 |
Michael Harris Guest
|
Posted: Tue Jun 15, 2004 12:37 am Post subject: Re: How can I change the threading model of an already exist |
|
|
Peter. The ide will not do this for you.
To change and rebuild the entire dll. try this for an MTA free threaded
(actuall both). model.
(MTA) is what you need.
* REMOVE and obj. tds. csm files from the project dir.
* ATL options. check multiple use.
(allows multiple clients to call into one process).
* Change base class
as sugested. any class using
public CComObjectRootEx<CComSingleThreadModel>,
change to
public CComObjectRootEx<CComMultiThreadModel>,
* change threading model.
below find the line
DECLARE_THREADING_MODEL(otSingle);
change to
DECLARE_THREADING_MODEL(otBoth);
this will fix threading issues on your end.
# From the IDE menu. Projects / Edit option source.
find. '<SYSDEFINES'
somewhere in the line it will have
_ATL_SINGLE_THREADED
change to
_ATL_BOTH_THREADED
save all/ close all.
reopen and check the ATL options. make sure they appear correctly.
sometimes the edit option source thing takes a couple of attempts.
checking the radio button in ATL options will fail to change the option
source at times.
--
Michael
"Peter"
| Quote: | How can I change the threading model of an already existing interface ?
I know it can't be done from the ATL tab of the project properties. The
option there seems pritty useless.
Some time ago I made an activeX dll with COM interface (without really
knowing much about COM).
I chose "single" as threading model when creating the COM object.
The person who needs to use the dll works under the .NET environment (vb).
rrrrr ... I have tried to debug small test apps using the dll but .net is
not for me ;-)
Following problem is something I have NOT been able to solve yet.
The dll class is instanciated in a new thread (in the .NET app) and once
the
first function is called an exception occurs :
"An unhandled exception of type 'System.InvalidCastException' occurred in
*.exe"
"Additional information: QueryInterface for interface dll.class failed."
I have been searching the newsgroups and all I can find is references to
the
app and com object not using the same threading model ?
(e.g.
[url]http://groups.google.be/groups?hl=nl&lr=&ie=UTF-8&threadm=78b36382.0210021252.52ba8a0%40posting.google.com&rnum=1&prev=/groups%3Fhl%3Dnl%26lr%3D%26ie%3DUTF-8%26q%3DI%27m%2Btrying%2Bto%2Bcreate%2Ba%2Bweb%2Bservice%2Bout%2Bof%2Ban%2Bexisting%2B(ATL%2BC%252B%252B)%2BCOM[/url] )
One other bit of information. In the ATL tab of the project properties I
use :
Instancing : "Single Use" and OLE init... "APARTMENTTHREADED"
So how can I resolve this issue ?
1. According to the link : "Register a proxy and stub for the interface.
The
easiest way to do this
is to register the type library that defines the interface." like the MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
2. Change the threading model of the interface ? To STA maybe ?
But how ?
3. I noticed that in .NET (from .NET help) the thread could possibly be
set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the person
who uses the dll creates such threads STA as well. Could that be the
solution ?
I'm out of ideas and I NEED to get this to work soon.
The code I put in the COM object (co)class is single threaded, hence me
chosing "single" when I created the COM object.
But I guess, because I use "Single use" in the Instancing property STA is
safe as well ??
Any other help is appreciated.
|
|
|
| Back to top |
|
 |
Peter Guest
|
Posted: Tue Jun 15, 2004 9:46 am Post subject: Re: How can I change the threading model of an already exist |
|
|
Thanks.
I'm not on my "developer PC" right now to try it but I have a question.
1. You say MTA, is this because you know this will solve the problem with
..NET ?
I mean, why MTA over STA for instance ?
2. You advice to change "Single Use" in the ATL to "Multiple Use"
I'm a bit scared of this. I'm not used to making threaded apps.
The dll is derived from a single thread application that I made !!
During debug mode (using "Single Use") I could see that each time I hit the
(.NET) test app button to create a new thread and make a new instance of the
COM object the constructor was called of the coclass and when the threads
were closed (app was closed) the destructor was called for each created
thread.
Using "Multi Use" I saw that each time the constructor was called but the
destructor was called only once ?
I'm not sure but it seemed each time a new instance was made but only one
instance was destroyed later on.
If it was the same instance all the time then calling then constructor again
doesn't seem a good idea ?? In my case variables are set-reset.
Given this information I'm also not sure if MTA is safe for me ? (Hence me
looking at STA)
What do you think ?
But if "Single Use", and each thread creates and uses it own instance of the
interface, inside the interface all is thread safe of course (?).
So that would be the solution then (?) right ?
"Michael Harris" <techonos-NO-SPAM- (AT) attbi (DOT) com> wrote
| Quote: | Peter. The ide will not do this for you.
To change and rebuild the entire dll. try this for an MTA free threaded
(actuall both). model.
(MTA) is what you need.
* REMOVE and obj. tds. csm files from the project dir.
* ATL options. check multiple use.
(allows multiple clients to call into one process).
* Change base class
as sugested. any class using
public CComObjectRootEx<CComSingleThreadModel>,
change to
public CComObjectRootEx<CComMultiThreadModel>,
* change threading model.
below find the line
DECLARE_THREADING_MODEL(otSingle);
change to
DECLARE_THREADING_MODEL(otBoth);
this will fix threading issues on your end.
# From the IDE menu. Projects / Edit option source.
find. '<SYSDEFINES'
somewhere in the line it will have
_ATL_SINGLE_THREADED
change to
_ATL_BOTH_THREADED
save all/ close all.
reopen and check the ATL options. make sure they appear correctly.
sometimes the edit option source thing takes a couple of attempts.
checking the radio button in ATL options will fail to change the option
source at times.
--
Michael
"Peter"
news:40ce19f1$1 (AT) newsgroups (DOT) borland.com...
How can I change the threading model of an already existing interface ?
I know it can't be done from the ATL tab of the project properties. The
option there seems pritty useless.
Some time ago I made an activeX dll with COM interface (without really
knowing much about COM).
I chose "single" as threading model when creating the COM object.
The person who needs to use the dll works under the .NET environment
(vb).
rrrrr ... I have tried to debug small test apps using the dll but .net
is
not for me ;-)
Following problem is something I have NOT been able to solve yet.
The dll class is instanciated in a new thread (in the .NET app) and once
the
first function is called an exception occurs :
"An unhandled exception of type 'System.InvalidCastException' occurred
in
*.exe"
"Additional information: QueryInterface for interface dll.class failed."
I have been searching the newsgroups and all I can find is references to
the
app and com object not using the same threading model ?
(e.g.
http://groups.google.be/groups?hl=nl&lr=&ie=UTF-8&threadm=78b36382.0210021252.52ba8a0%40posting.google.com&rnum=1&prev=/groups%3Fhl%3Dnl%26lr%3D%26ie%3D |
UTF-8%26q%3DI%27m%2Btrying%2Bto%2Bcreate%2Ba%2Bweb%2Bservice%2Bout%2Bof%2Ban
%2Bexisting%2B(ATL%2BC%252B%252B)%2BCOM )
| Quote: |
One other bit of information. In the ATL tab of the project properties
I
use :
Instancing : "Single Use" and OLE init... "APARTMENTTHREADED"
So how can I resolve this issue ?
1. According to the link : "Register a proxy and stub for the interface.
The
easiest way to do this
is to register the type library that defines the interface." like the MS
person suggests ?
I tried that and it doesn't seem to make a difference.
I have no clue what it does ? I ran it from the type library editor.
What is the difference with registering the active x server ?
The interface works when used in the main program thread without ever
registering the type library ??
2. Change the threading model of the interface ? To STA maybe ?
But how ?
3. I noticed that in .NET (from .NET help) the thread could possibly be
set
to STA or MTA.
So suppose I can change the com interface to STA and make sure the
person
who uses the dll creates such threads STA as well. Could that be the
solution ?
I'm out of ideas and I NEED to get this to work soon.
The code I put in the COM object (co)class is single threaded, hence me
chosing "single" when I created the COM object.
But I guess, because I use "Single use" in the Instancing property STA
is
safe as well ??
Any other help is appreciated.
|
|
|
| Back to top |
|
 |
Michael Harris Guest
|
Posted: Tue Jun 15, 2004 12:00 pm Post subject: Re: How can I change the threading model of an already exist |
|
|
Let me review a little.
< Some time ago I made an activeX dll with COM interface }
We are still talking about an ActiveX DLL. correct.?
| Quote: | If it was the same instance all the time then calling then constructor
again
doesn't seem a good idea ?? In my case variables are set-reset.
|
If you need a single instance of the com object
calling process in a com dll>.
DECLARE_CLASSFACTORY_SINGLETON(TMyComObject_xxxImpl)
If you have ststic variables in the dll.. you may want to consider a code
review.
--
Michael
"Peter" wrote in message ...
| Quote: | Thanks.
I'm not on my "developer PC" right now to try it but I have a question.
1. You say MTA, is this because you know this will solve the problem with
.NET ?
I mean, why MTA over STA for instance ?
2. You advice to change "Single Use" in the ATL to "Multiple Use"
I'm a bit scared of this. I'm not used to making threaded apps.
The dll is derived from a single thread application that I made !!
During debug mode (using "Single Use") I could see that each time I hit
the
(.NET) test app button to create a new thread and make a new instance of
the
COM object the constructor was called of the coclass and when the threads
were closed (app was closed) the destructor was called for each created
thread.
Using "Multi Use" I saw that each time the constructor was called but the
destructor was called only once ?
I'm not sure but it seemed each time a new instance was made but only one
instance was destroyed later on.
If it was the same instance all the time then calling then constructor
again
doesn't seem a good idea ?? In my case variables are set-reset.
Given this information I'm also not sure if MTA is safe for me ? (Hence
me
looking at STA)
What do you think ?
But if "Single Use", and each thread creates and uses it own instance of
the
interface, inside the interface all is thread safe of course (?).
So that would be the solution then (?) right ?
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|