|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
C++/C# interop causes OleInitialize (STA) to fail?model to MTA so that OleInitialize will fail? I have a mostly C++ app that calls a single C# class DLL. Only one source file in the C++ app is compiled as managed (with /clr) – the single file in which only one of the many functions creates a class object from the C# DLL and invokes its methods (to decode an XML file the easy way). During normal execution my code eventually creates an instance of an MSFlexGrid ocx object (a grid control with column and row headers), which in turn calls AfxOleInit and therefore OleInitialize. Works fine in normal execution. I believe OleInitialize is by default STA. By “normal†execution I mean the situation when I do not execute any code in that single C++ file that calls into the C# DLL. If, however, I call functions in that C++ file (even if they do not call the only function that invokes C#), then when I create the MSFlexGrid object the internal call to OleInitialize fails with the Trace message “Warning: OleInitialize returned scode = RPC_E_CHANGED_MODE ($80010106)â€. From the help files it sounds like OleInitialize expects to be run in STA mode, and the error message means “A previous call to CoInitializeEx specified the concurrency model for this apartment as multithread apartment (MTA)â€. I tried putting breakpoints on every bit of MFC / ATL source code that calls OleInitialize or CoInitialize to see if I could find the offender, but nothing trapped. If I create the MSFlexGrid before invoking C#, all is fine, and if I call OleInitialize at the very beginning of my app all is fine. But I’m worried there is a threading disaster waiting to happen. What’s the deal? Take a look at the Paul Dilascia's CSTAThread class here
http://msdn.microsoft.com/msdnmag/issues/05/03/CATWork/ -- Show quoteHide quoteCheers Check Abdoul [VC++ MVP] ----------------------------------- "Bill Cumming" <BillCumm***@discussions.microsoft.com> wrote in message news:280D4F6A-0BB0-4841-8AE1-51E7117222AE@microsoft.com... > Is there something about C++ / C# interop that initializes the threading > model to MTA so that OleInitialize will fail? > > I have a mostly C++ app that calls a single C# class DLL. Only one source > file in the C++ app is compiled as managed (with /clr) - the single file in > which only one of the many functions creates a class object from the C# DLL > and invokes its methods (to decode an XML file the easy way). > > During normal execution my code eventually creates an instance of an > MSFlexGrid ocx object (a grid control with column and row headers), which in > turn calls AfxOleInit and therefore OleInitialize. Works fine in normal > execution. I believe OleInitialize is by default STA. > > By "normal" execution I mean the situation when I do not execute any code in > that single C++ file that calls into the C# DLL. If, however, I call > functions in that C++ file (even if they do not call the only function that > invokes C#), then when I create the MSFlexGrid object the internal call to > OleInitialize fails with the Trace message "Warning: OleInitialize returned > scode = RPC_E_CHANGED_MODE ($80010106)". > > From the help files it sounds like OleInitialize expects to be run in STA > mode, and the error message means "A previous call to CoInitializeEx > specified the concurrency model for this apartment as multithread apartment > (MTA)". I tried putting breakpoints on every bit of MFC / ATL source code > that calls OleInitialize or CoInitialize to see if I could find the offender, > but nothing trapped. > > If I create the MSFlexGrid before invoking C#, all is fine, and if I call > OleInitialize at the very beginning of my app all is fine. But I'm worried > there is a threading disaster waiting to happen. > > What's the deal? > That's roughly what I tried, and it does indeed solve the problem to call
CoInitialize (or OleInitialize) before the Framework calls it with COINIT_MULTITHREADED. Two questions: 1) My original question: is this a threading disaster waiting to happen by setting the mode to STA? Are there other conflicts I should be aware of? 2) By setting the mode to STA will that disable the garbage collector? Thanks! Show quoteHide quote "CheckAbdoul" wrote: > Take a look at the Paul Dilascia's CSTAThread class here > > http://msdn.microsoft.com/msdnmag/issues/05/03/CATWork/ > -- > Cheers > Check Abdoul [VC++ MVP] > ----------------------------------- > Hi,
> That's roughly what I tried, and it does indeed solve the problem to call Definitely not. The runtime simply defaults to MTA, if it> CoInitialize (or OleInitialize) before the Framework calls it with > COINIT_MULTITHREADED. > > Two questions: > 1) My original question: is this a threading disaster waiting to happen by > setting the mode to STA? Are there other conflicts I should be aware of? detects that CoInitialize was not called before, and if the main entry point of an executable assembly doesn't apply the STAThreadAttribute. > 2) By setting the mode to STA will that disable the garbage collector? No.Rob Show quoteHide quote > > Thanks! > > "CheckAbdoul" wrote: > > >>Take a look at the Paul Dilascia's CSTAThread class here >> >> http://msdn.microsoft.com/msdnmag/issues/05/03/CATWork/ >>-- >>Cheers >>Check Abdoul [VC++ MVP] >>----------------------------------- >> > > Bill,
> Is there something about C++ / C# interop that initializes the threading Well, by default the CLR will initialize managed threads into the MTA. In C# > model to MTA so that OleInitialize will fail? or VB, you can usually prevent this for the application's main thread by tagging the entry point method with the [STAThread] attribute. Unfortunately, this doesn't work reliably in Managed C++ because the main() function is not actually the application's entry point (the actual one is in the CRT). Sounds like this might help: http://support.microsoft.com/kb/824480 While the article applies directly to the issue I have, the proposed
solution is more appropriate for a command line app since you can more easily get at the startup routine. But the article accurately describes my situation. I merely added a call to OleInitialize(NULL) very early on in my app before any calls to the Framework (which initializes COM as MTA), and that seems to have solved my problem. Thanks for your help! Bill,
> Glad to know. If your app does not have a managed entry point, then that > While the article applies directly to the issue I have, the proposed > solution is more appropriate for a command line app since you can more > easily > get at the startup routine. But the article accurately describes my > situation. > > I merely added a call to OleInitialize(NULL) very early on in my app > before > any calls to the Framework (which initializes COM as MTA), and that seems > to > have solved my problem. probably works. The problem with this, if there's a managed entry point, is that you're not guaranteed it will work because you can't predict what the runtime did before you...
ExecutionEngineException -> Code sample that triggers EEE
How to load binary image with 1 Bit Per Pixel ? class member initialization What rong witht his simple snippit of code? How to use File.Exists and Handle Insufficient Permissions Random Class stops generating Rands? communication I need help, please. =S Animate content of picture box check disabled |
|||||||||||||||||||||||