Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

static unmanaged object in mixed exe

29 views
Skip to first unread message

shu

unread,
Jan 30, 2006, 7:30:46 PM1/30/06
to
Is it legal to declare a static instance of an object compiled in a "No
CLR support" .obj?

I have the next .cpp, in which I mix definition of CTest and declarion
of the static var in the same .cpp to make the example shorter :

class CTest
{
public:
CTest();
~CTest(); // <- Important to reproduce
};

CTest::CTest()
{
}

CTest::~CTest()
{
}

static CTest s_CTest; // Here!!: _CrtIsValidHeapPointer

I also have 2 other additional .cpp in the project: AssemblyInfo.cpp
and Main.cpp, both compiled with the /clr switch.

My problem arises when calling the unmanaged static constructor... it
calls the unmanaged crt _atexit function in order to subscribe the
destructor to the list of functions that get called at program exit,
but it seems like the CRT is not initialized yet!!

Any ideas?

dsh...@gmail.com

unread,
Jan 31, 2006, 8:18:56 AM1/31/06
to
Hello,

I find this problem a few days ago.
And I know only one resolution for this problem:

Every .cpp file which contains global variable of type with non-trivial
constructor/destructor must be compiled with /clr switch.

In my opinion, this is a compiler bug.

Best regards,
DS

Holger Grund

unread,
Jan 31, 2006, 9:12:06 AM1/31/06
to
<dsh...@gmail.com> wrote

> Hello,
>
> I find this problem a few days ago.
> And I know only one resolution for this problem:
>
> Every .cpp file which contains global variable of type with non-trivial
> constructor/destructor must be compiled with /clr switch.
>
> In my opinion, this is a compiler bug.
>

I think we've had that one before. It's really an issue with CRT
initialization. The initialization code expects the constructors
to be encoded (with Windows EncodePointer function), which
they are not. Therefore the code passes a bogus pointer to
realloc, which asserts in debug mode. Usually, the CRT registers
an early init function which does the encoding (IIRC it's
pre_c_init). You'll notice that this function is not present
in managed exe's. I suggest you open a bug at

http://lab.msdn.microsoft.com/productfeedback/

BTW: While it might sound odd at first, that a global object has
a destructor effectively requires initialization code.

The initialization code will register the object for destruction
by calling atexit (or a similar function).

-hg


Holger Grund

unread,
Jan 31, 2006, 11:21:05 AM1/31/06
to
"Holger Grund" <holger...@remove.ix-n.net> wrote

> I think we've had that one before. It's really an issue with CRT
> initialization. The initialization code expects the constructors
> to be encoded (with Windows EncodePointer function), which
> they are not. Therefore the code passes a bogus pointer to
> realloc, which asserts in debug mode. Usually, the CRT registers
> an early init function which does the encoding (IIRC it's
> pre_c_init). You'll notice that this function is not present
> in managed exe's. I suggest you open a bug at
>

My bad! Looking at my notes, it seemed to be a bug in the
project wizard. The wizard sets the linker option /ENTRY:main
which bypasses CRT initialization.

Can you try the following in your project:

- Project Settings/Configuration Properties/Linker/System
Clear SubSystem (select "<inherit from ...>" which should
result in "not set").
- Project Settings/Configuration Properties/Linker/Advanced
Clear entrypoint (again by selecting "<inherit from ...>")

Does this work for you?

-hg


DSheva

unread,
Feb 1, 2006, 4:45:36 AM2/1/06
to
Hello, Holger,

Yes, this work fine. BUT, this makes our application as a console
(console windows opened on start up and this is really BAD). Problem
with native globale variable occured only with Windows Forms projects.

See also
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=1134e07a-5c95-498f-bd26-2f4f1af866d5
You can find my test solution attached to this feedback.

Best regards,
DS

DSheva

unread,
Feb 1, 2006, 5:44:15 AM2/1/06
to
Hello,

I found new way to resolve this problem:

"- Project Settings/Configuration Properties/Linker/Advanced
Clear entrypoint (again by selecting "<inherit from ...>") " (as Holger
wrote)

+

add the following code near main() definition:

int main(array<System::String ^> ^args)
{
<...>
}

int __stdcall WinMain(int hInstance, int hPrevInstance, void
*lpCmdLine, int nShowCmd)
{
return main(gcnew array<System::String^>(0));
}


Code doesn't contain initialization of the args parameter and need to
be extended.
But, in my opinion, this is right way (no console shown).

DSheva

unread,
Feb 1, 2006, 6:26:52 AM2/1/06
to
Hello,

I found new way to resolve this problem :-) :

Just change
/entry:main
to
/entry:?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z

No other changes need.

Best regards,
DS

0 new messages