473,583 Members | 3,134 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

VC 2005 Beta 2: How to set STA ApartmentState

Hello.

I'm moving an application VC 2003 to VC 2005 Beta2. I need to set STA
ApartmentState model so the drag & drop registration can work.

I used to do
System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;
as the first statment of _tWinMain and also in the DllMain of my mixed mode
assemblies.

On VC 2005 I can't do this statment in DllMain, so I was oriented by Carl
Daniel and Kapil to create a static instance of a class that makes the
statment on its constructor. I included a class like the following in all
mixed mode DLLs, hoping the static instances would be initialized on the
..cctors.

__gc class QIVCadCctor
{
public:
QIVCadCctor()
{
System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;
}

static QIVCadCctor* cadCctor = new QIVCadCctor();
};

Even doing this, when the program tries to execute

System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;

on _tWinMain, I get the following error message on my debug output window:

Managed Debugging Assistant 'InvalidApartme ntStateChange' has detected a
problem in 'c:\Fontes\QiCa d.NET\QiCad.NET .exe'.
Additional Information: Thread is attempting to set the apartment state
to STA, but it has already been set to MTA.
See
C:\WINDOWS\Micr osoft.NET\Frame work\v2.0.50215 \sdk\bin\mdaBoi lerplate.exe.md a.config
for documentation.

Does anyone know what is missing?

Thanks in advance.

Regards,
Adriano.
Nov 17 '05 #1
10 2572
Adriano Coser wrote:
Hello.

I'm moving an application VC 2003 to VC 2005 Beta2. I need to set STA
ApartmentState model so the drag & drop registration can work.

I used to do
System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;
as the first statment of _tWinMain and also in the DllMain of my
mixed mode assemblies.

On VC 2005 I can't do this statment in DllMain, so I was oriented by
Carl Daniel and Kapil to create a static instance of a class that makes
the
statment on its constructor. I included a class like the following in
all mixed mode DLLs, hoping the static instances would be initialized on
the .cctors.

__gc class QIVCadCctor
{
public:
QIVCadCctor()
{
System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;
}

static QIVCadCctor* cadCctor = new QIVCadCctor();
};

Even doing this, when the program tries to execute

System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;

on _tWinMain, I get the following error message on my debug output
window:
Managed Debugging Assistant 'InvalidApartme ntStateChange' has
detected a problem in 'c:\Fontes\QiCa d.NET\QiCad.NET .exe'.
Additional Information: Thread is attempting to set the apartment
state to STA, but it has already been set to MTA.
See
C:\WINDOWS\Micr osoft.NET\Frame work\v2.0.50215 \sdk\bin\mdaBoi lerplate.exe.md a.config
for documentation.

Does anyone know what is missing?


I can't tell you anything very specific, but clearly - something else is
running, either in DllMain itself, or in the .cctor that has already called
CoInitializeEx and set the current thread to be part of the MTA. You might
be able to debug it by setting a breakpoint at CoInitializeEx( ), and
examining the call stack.

-cd
Nov 17 '05 #2
Hello Carl.

I didn't find any calls to CoInitialize or CoInitializeEx in my code. Also,
I don't know how to set a breakpoint over this function.

Is there any other cause to ApartmentState to set to MTA before _tWinMain
entry point?

Thanks for your help.

Adriano.
AltoQi - Tecnologia Aplicada à Engenharia Adriano Coser Departamento de
Desenvolvimento Tel.: (48) 239-7000 ramal: 7069 e-mail: co***@altoqi.co m.br
website: www.altoqi.com.br
"Carl Daniel [VC++ MVP]" <cp************ *************** **@mvps.org.nos pam>
escreveu na mensagem news:%2******** ********@TK2MSF TNGP10.phx.gbl. ..
Adriano Coser wrote:
Hello.

I'm moving an application VC 2003 to VC 2005 Beta2. I need to set STA
ApartmentState model so the drag & drop registration can work.

I used to do
System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;
as the first statment of _tWinMain and also in the DllMain of my
mixed mode assemblies.

On VC 2005 I can't do this statment in DllMain, so I was oriented by
Carl Daniel and Kapil to create a static instance of a class that makes
the
statment on its constructor. I included a class like the following in
all mixed mode DLLs, hoping the static instances would be initialized on
the .cctors.

__gc class QIVCadCctor
{
public:
QIVCadCctor()
{
System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;
}

static QIVCadCctor* cadCctor = new QIVCadCctor();
};

Even doing this, when the program tries to execute

System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;

on _tWinMain, I get the following error message on my debug output
window:
Managed Debugging Assistant 'InvalidApartme ntStateChange' has
detected a problem in 'c:\Fontes\QiCa d.NET\QiCad.NET .exe'.
Additional Information: Thread is attempting to set the apartment
state to STA, but it has already been set to MTA.
See
C:\WINDOWS\Micr osoft.NET\Frame work\v2.0.50215 \sdk\bin\mdaBoi lerplate.exe.md a.config
for documentation.

Does anyone know what is missing?


I can't tell you anything very specific, but clearly - something else is
running, either in DllMain itself, or in the .cctor that has already
called CoInitializeEx and set the current thread to be part of the MTA.
You might be able to debug it by setting a breakpoint at CoInitializeEx( ),
and examining the call stack.

-cd

Nov 17 '05 #3
Hi Carl.

I've just realized that the static instances I created to set the apartment
state on my DLLs (like the following) are not initialized before _tWinMain.

I put breakpoints on DllMain and on the constructor of QIVCadCctor and the
program only stops on DllMain. Could this be the problem? What else can I do
to call managed code on a mixed mode DLL initialization?

__gc class QIVCadCctor
{
public:
QIVCadCctor()
{
System::Threadi ng::Thread::Cur rentThread->ApartmentSta te =
System::Threadi ng::ApartmentSt ate::STA;
}
static QIVCadCctor* cadCctor = new QIVCadCctor();
};

Thanks for your help.
Adriano.
Nov 17 '05 #4
Adriano Coser wrote:
Hi Carl.

I've just realized that the static instances I created to set the
apartment state on my DLLs (like the following) are not initialized
before _tWinMain.
I put breakpoints on DllMain and on the constructor of QIVCadCctor
and the program only stops on DllMain. Could this be the problem?
What else can I do to call managed code on a mixed mode DLL
initialization?


Why not simply set the apartment to the STA in native code instead of
managed? I would assume that a simple call to CoInitialize() in DllMain()
would be sufficient (I hope I'm not getting myself in trouble by not
verifying that it's actually safe to call CoInitialize() from DllMain()).

-cd
Nov 17 '05 #5
Carl, I think it's OK now.

I called CoInitializeEx( NULL, COINIT_APARTMEN TTHREADED); on DllMain of one
of my DLLs when reason == DLL_PROCESS_ATT ACH. Then I called CoUninitialize( )
when read == DLL_PROCESS_DET ACH.

Now the program is running! Thanks a lot, you made my weekend.

But in the output window I'm getting the inverse message that I had before:

Managed Debugging Assistant 'InvalidApartme ntStateChange' has detected a
problem in 'c:\Fontes\QiCa d.NET\QiCad.NET .exe'.
Additional Information: Thread is attempting to set the apartment state to
MTA, but it has already been set to STA.

Do you believe I should call CoInitializeEx in all my mixed mode DLLs?

Thanks again for your help.

Adriano.

AltoQi - Tecnologia Aplicada à Engenharia Adriano Coser Departamento de
Desenvolvimento Tel.: (48) 239-7000 ramal: 7069 e-mail: co***@altoqi.co m.br
website: www.altoqi.com.br
"Carl Daniel [VC++ MVP]" <cp************ *************** **@mvps.org.nos pam>
escreveu na mensagem news:%2******** ********@TK2MSF TNGP14.phx.gbl. ..
Adriano Coser wrote:
Hi Carl.

I've just realized that the static instances I created to set the
apartment state on my DLLs (like the following) are not initialized
before _tWinMain.
I put breakpoints on DllMain and on the constructor of QIVCadCctor
and the program only stops on DllMain. Could this be the problem?
What else can I do to call managed code on a mixed mode DLL
initialization?


Why not simply set the apartment to the STA in native code instead of
managed? I would assume that a simple call to CoInitialize() in DllMain()
would be sufficient (I hope I'm not getting myself in trouble by not
verifying that it's actually safe to call CoInitialize() from DllMain()).

-cd

Nov 17 '05 #6
Adriano Coser wrote:
Carl, I think it's OK now.

I called CoInitializeEx( NULL, COINIT_APARTMEN TTHREADED); on DllMain
of one of my DLLs when reason == DLL_PROCESS_ATT ACH. Then I called
CoUninitialize( ) when read == DLL_PROCESS_DET ACH.

Now the program is running! Thanks a lot, you made my weekend.

But in the output window I'm getting the inverse message that I had
before:
Managed Debugging Assistant 'InvalidApartme ntStateChange' has
detected a problem in 'c:\Fontes\QiCa d.NET\QiCad.NET .exe'.
Additional Information: Thread is attempting to set the apartment
state to MTA, but it has already been set to STA.

Do you believe I should call CoInitializeEx in all my mixed mode DLLs?


Actually, as a general principle I don't believe you should ever try to
enter an apartment in a DLL unless you're doing it in a thread that your DLL
"owns" (creates and managed the lifetime of). Perhaps there's something
unique about your situation that requires it, but I'd try to get rid of the
requirement rather than tilting at windmills trying to find a way to honor
it.

-cd
Nov 17 '05 #7


"Adriano Coser" wrote:
Carl, I think it's OK now.

I called CoInitializeEx( NULL, COINIT_APARTMEN TTHREADED); on DllMain of one
of my DLLs when reason == DLL_PROCESS_ATT ACH. Then I called CoUninitialize( )
when read == DLL_PROCESS_DET ACH.

Now the program is running! Thanks a lot, you made my weekend.

But in the output window I'm getting the inverse message that I had before:

Managed Debugging Assistant 'InvalidApartme ntStateChange' has detected a
problem in 'c:\Fontes\QiCa d.NET\QiCad.NET .exe'.
Additional Information: Thread is attempting to set the apartment state to
MTA, but it has already been set to STA.

Do you believe I should call CoInitializeEx in all my mixed mode DLLs?

Thanks again for your help.

Adriano.

AltoQi - Tecnologia Aplicada Ã* Engenharia Adriano Coser Departamento de
Desenvolvimento Tel.: (48) 239-7000 ramal: 7069 e-mail: co***@altoqi.co m.br
website: www.altoqi.com.br
"Carl Daniel [VC++ MVP]" <cp************ *************** **@mvps.org.nos pam>
escreveu na mensagem news:%2******** ********@TK2MSF TNGP14.phx.gbl. ..
Adriano Coser wrote:
Hi Carl.

I've just realized that the static instances I created to set the
apartment state on my DLLs (like the following) are not initialized
before _tWinMain.
I put breakpoints on DllMain and on the constructor of QIVCadCctor
and the program only stops on DllMain. Could this be the problem?
What else can I do to call managed code on a mixed mode DLL
initialization?


Why not simply set the apartment to the STA in native code instead of
managed? I would assume that a simple call to CoInitialize() in DllMain()
would be sufficient (I hope I'm not getting myself in trouble by not
verifying that it's actually safe to call CoInitialize() from DllMain()).

-cd

No, you should never call a method from DllMain which has managed code in it
or calls another method with managed code. You can easily get into a loader
lock problem.

The recommended way to move code out of DllMain is to declare a global
managed object. In the constructor of that object you should call the code
which you were initially calling in DllMain. The module constructor will
initialize see this global and call the constructor.
Note: A managed object here is not a ref/value class object. You cannot
have global ref objects. Here managed object means a native class compiled
with /clr or under #pragma managed.

The reason is this works is because in mixed assemblies, the initializations
are done by the module constructor. It is very important to remember that the
module constructor for an assembly is called only if some managed code is
first executed either in the host assembly or in your Dll itself. If you dont
"use" that managed object you will never invoke the module constructor, thus
your constructor will never be called and data will be uninitialized.

Let me give you an example,
///////////////////////
cl /clr /LD /Zi 1.cpp
cl /clr /EHa t.cpp /Zi /link 1.lib
/////////////////////

/////////////////
//1.cpp

#pragma once
#include <stdio.h>
#include <windows.h>
class __declspec(dlle xport) A
{
public:
A()
{
System::Console ::WriteLine("Mo dule constructor doing initialization based
on the global instance of the class A\n");
System::Console ::WriteLine("Co de from DllMain, now in constructor
executed\n");
}
void foo()
{
printf("foo called so that the linker knows not to throw away an unuse
object in t.cpp \n");
}
};

#pragma unmanaged
// Global instance of object
A obj;

extern "C"
BOOL WINAPI DllMain(HINSTAN CE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// REMOVE ALL MANAGED CODE FROM DLLMAIN.
return true;
}

///////////////////////////////
//t.cpp

#include <windows.h>
using namespace System;
#include <stdio.h>
#using "1.dll"
class __declspec(dlli mport) A
{
public:
void foo();
};
int main()
{
LoadLibrary("1. dll");
A obj;
obj.foo();
}

Nov 17 '05 #8
Kapil Khosla [MSFT] wrote:
No, you should never call a method from DllMain which has managed
code in it or calls another method with managed code. You can easily
get into a loader lock problem.


Note that he's calling CoInitializeEx, which, last I checked, has no managed
code in it. Of course, that alone does not mean it's safe to call it from
DllMain, and I make no claim that it is.

-cd
Nov 17 '05 #9


"Carl Daniel [VC++ MVP]" wrote:
Kapil Khosla [MSFT] wrote:
No, you should never call a method from DllMain which has managed
code in it or calls another method with managed code. You can easily
get into a loader lock problem.


Note that he's calling CoInitializeEx, which, last I checked, has no managed
code in it. Of course, that alone does not mean it's safe to call it from
DllMain, and I make no claim that it is.

-cd

You are right. But it always makes me nervous when someone calls a method in
DllMain and that method potentially could have managed code which tries to
load the CLR.

The original method you mention of having code in the managed object's
constructor is much better and should work. Although I think the
interpretation of Adriano was not quite correct. He created a static object
inside the managed class but it should have been a global like the example I
posted so that the module constructor can do the initialization when the
assembly is loaded.

Thanks Carl.
Kapil
Nov 17 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

48
3693
by: ik | last post by:
ERROR after uninstalling SQL Server 2005 Express I get this message, SQLDMO has not been registered. Please re-run your setupand contact your system administrator. GREAT!!! ReInstalled SQL SERVER 2000 after playing around with SQL Server 2005...
3
1321
by: Mike P | last post by:
I've been using Visual Studio 2005 Beta 1 for the last few weeks, and I now want to try using SQL Server 2005 Beta with it. I've been to the Microsoft URL http://lab.msdn.microsoft.com/express/sql/ which allows you to download a product called SQL Server Express (April CTP). It also specifies that you must uninstall all Express software and...
10
1963
by: Bonj | last post by:
Hi I installed .NET 2005 express edition, and am about to unnistall it again because it can't seem to be able to even insert a resource file into a project. Can anyone tell me is this right? Should it be able to? I know it's express edition, and therefore limited functionality, but surely resources are quite fundamental? Also, once it's...
5
1633
by: Adriano Coser | last post by:
Hello. I'm moving an application from VC 2003 to VC 2005 Beta2. In mixed mode DLLs I need to set System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA; so the drag and drop registration can work. I used to do this in DllMain and it worked fine. But now I can't call managed code from this...
1
1762
by: Peted | last post by:
Hi, sorry if this isnt the correct newsgroups for this questions but im using vc++ 2005 express edition beta2 for learning to program vc++ ..net, as in winforms applications and i was wondering if can anyone point me to some sample code for writing to connect to a existing telnet server I just want to be able to establish a connection,...
6
1682
by: Heloise | last post by:
Hi, ..NET version: Visual C++ 2005 Express Edition Beta OS: XP I have a set of dlls built with .NET 2003. They are unmanaged C++ and C code. I am writing a managed C++ dll layer to call my unmanaged libraries using IJW.
13
1932
by: Howard Kaikow | last post by:
I just visited the MSFT web site and saw the comparison/pricing of the different VS 2005 versions. I was looking for a statement of the system requirements for VS Pro and VSTO, could not find. Also, more details on the differences between VS Pro and VSTO. For example, can VSTO be used to create a DLL, in particular, a DLL that can be used...
4
2973
by: Airw0lf | last post by:
Hi all, would appreciate help with some trouble I'm having after using the Visual C++ 2005 Express Conversion Wizard on my Visual C++ .NET 2003 project. The wizard completed successfully with only warnings about using a "fully qualified name with the use of the address-of operator (e.g. &ClassName::MemberFunctionName)". I added the &...
3
3175
by: pine | last post by:
hi! i just joined this group today after a colleague told me about it. anyway, i'm new to SQL and haven't tried installing any version of it. I do have vb 6.0 though on my pc. My problem is that I can't install SQL server 05 EE, VB 2005 or VW 2005. I have downloaded all of the installer from the Microsoft site as well as the dotnetfix which...
0
8328
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7936
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
8195
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5701
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5375
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3820
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3845
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2334
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1434
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.