VC 2005 Beta 2 - How to: Explicitly Define a Module Constructor (.cctor)

A

Adriano Coser

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 point. I understand that I must provide a module
constructor (.cctor) to do managed code initializations.

I couldn't find information on how to do this. The help of my Express
Edition gives me a script error when I try to access the topic "How to:
Explicitly Define a Module Constructor (.cctor)".

Does anyone have this orientations? Is this the right way to init managed
code on a mixed mode DLL?

Thanks in advance.
Regards,
Adriano.
 
C

Carl Daniel [VC++ MVP]

Adriano said:
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 point. I understand that I must provide a
module constructor (.cctor) to do managed code initializations.

I couldn't find information on how to do this. The help of my Express
Edition gives me a script error when I try to access the topic "How
to: Explicitly Define a Module Constructor (.cctor)".

Does anyone have this orientations? Is this the right way to init
managed code on a mixed mode DLL?

Just put the code in the constructor of a managed object with file scope and
static storage duration and it'll automatically run in the .cctor.

-cd
 
G

Guest

I'm moving an application from VC 2003 to VC 2005 Beta2. In mixed
Just put the code in the constructor of a managed object with file scope and
static storage duration and it'll automatically run in the .cctor.

-cd
Generally using a module constructor is not recommended. Please refer to the
article
http://msdn2.microsoft.com/library/ms173266(en-us,vs.80).aspx
which contains in detail what Carl explains on how to do Initialization of
Mixed assemblies.
Thanks,
Kapil
 
A

Adriano Coser

Carl and Kapil.

I added to my DLLs a source file like this:

__gc class QIVCadCctor
{
public:
QIVCadCctor()
{
System::Threading::Thread::CurrentThread->ApartmentState =
System::Threading::ApartmentState::STA;
}

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

Is this right? The constructor will execute during .cctor initialization?

I made this in all DLLs with clr support, but I'm still getting the drag &
drop registration failure.

In fact, I get an exception on my debug output window when I try to set STA
apartment state model:

Managed Debugging Assistant 'InvalidApartmentStateChange' has detected a
problem in 'c:\Fontes\QiCad.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\Microsoft.NET\Framework\v2.0.50215\sdk\bin\mdaBoilerplate.exe.mda.config
for documentation.

Am I missing something?

Thanks for your help.

Adriano.
 
W

Willy Denoyette [MVP]

Adriano Coser said:
Carl and Kapil.

I added to my DLLs a source file like this:

__gc class QIVCadCctor
{
public:
QIVCadCctor()
{
System::Threading::Thread::CurrentThread->ApartmentState =
System::Threading::ApartmentState::STA;
}

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

Is this right? The constructor will execute during .cctor initialization?

I made this in all DLLs with clr support, but I'm still getting the drag &
drop registration failure.

In fact, I get an exception on my debug output window when I try to set
STA apartment state model:

Managed Debugging Assistant 'InvalidApartmentStateChange' has detected
a problem in 'c:\Fontes\QiCad.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\Microsoft.NET\Framework\v2.0.50215\sdk\bin\mdaBoilerplate.exe.mda.config
for documentation.

Am I missing something?

Thanks for your help.

Adriano.

The calling thread runs in an MTA, so you can't change it's apartment once
set to MTA (after all it's bad practice to set the apartment in a DLL).

You have two options to solve this issue:
1.
- Remove the STA stuff from the constructor.
- Create new thread
- Set its apartment state to STA
- Start the thread
- Create/call your object in the newly created thread.

2. (preferably)
Set the 'main' thread apartment to STA (the thread running the main entry).
You can do this by means of the linker argument
/CLRTHREADATTRIBUTE:{STA|MTA|NONE} and simply create/call your object on the
main thread.


Willy.
 
A

Adriano Coser

Thanks a lot Willy.

I've just added /CLRTHREADATTRIBUTE:STA to the application linker command
line and it worked fine. Now I don't need to do nothing special on my DLLs.

Regards,
Adriano.

AltoQi - Tecnologia Aplicada à Engenharia Adriano Coser Departamento de
Desenvolvimento Tel.: (48) 239-7000 ramal: 7069 e-mail: (e-mail address removed)
website: www.altoqi.com.br
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top