Managed method in Native Class ?

H

Herby

Is possible to have a managed method within a Native(un-managed) class
within a \clr project?

E.g.

class myClass
{
public:
#pragma managed
void myMethod(void);

};

I get an error when attempting to compile above about #pragma managed
must be used at global scope!

Is there some way to achieve this?
If not, why not?

Thanks in advance.
 
H

Herby

Its interesting to note that given

//myClass.h

class myClass
{
public:
void myMethod(void);
};

And the following module compiled as \clr


// myClass.cpp
#pragma unmanaged
void myClass::myMethod(void)
{
}

works correctly, if i put any managed data in here, will generate
errors.

But if i compile the module unmanaged with a \clr project and then

// myClass.cpp
#pragma managed
void myClass::myMethod(void)
{
}

Will not work. Big shame for me!
Why cannot this be made to work?

Please help...
 
W

Willy Denoyette [MVP]

Herby said:
Its interesting to note that given

//myClass.h

class myClass
{
public:
void myMethod(void);
};

And the following module compiled as \clr


// myClass.cpp
#pragma unmanaged
void myClass::myMethod(void)
{
}

myMethod is a member of a native C++ class, the code generated for the
method is managed code (IL), the object data members (there aren't any) is
native data.
The class instance is on the process heap just like a regular C++ objects,
the members occupy a slot in the objects vtable laid-out by the compiler.
So this is quite normal that it works.
works correctly, if i put any managed data in here, will generate
errors.

But if i compile the module unmanaged with a \clr project and then

// myClass.cpp
#pragma managed
void myClass::myMethod(void)
{
}

Will not work. Big shame for me!
Why cannot this be made to work?

This can't work, a managed method cannot be a member of a native class.
Managed methods must be members of a managed class, stored on the GC heap
and laid-out by the CLR.
Please read more about the difference between object models in msdn.
 
H

Herby

Perhaps I am being misunderstood.

If i compile the module containing my native class with \clr, then
within my native methods i can create and use managed types, by
default. This gives me mixed mode type functionality, which is what i
require.
I only want to do this within one of the methods of my native class.
I want the remainder methods to remain native. They have no need to
access managed types.

So for all the other methods i would then have to precede them with
#pragma unmanaged to ensure they stay native given the module has been
compiled \clr.
This is alot of editing, i just want to do the inverse.
Default to compiling them native unless you hit #pragma managed.

I dont see the point in #pragma managed if it can only be used within a
module compiled with \clr?
 
W

Willy Denoyette [MVP]

Herby said:
Perhaps I am being misunderstood.

If i compile the module containing my native class with \clr, then
within my native methods i can create and use managed types, by
default. This gives me mixed mode type functionality, which is what i
require.
I only want to do this within one of the methods of my native class.
I want the remainder methods to remain native. They have no need to
access managed types.

But a method in a native class must be a native method, it can't be a
managed method. You aren't fully understanding the meaning of mixed mode I
guess. Mixed mode means that you can have native classes and managed classes
in the same compilation unit, but you can't have native member functions in
managed classes, nor can you have managed methods as members of native
classes. The reason is the fundamental difference between the managed object
model and the unmanaged object model.
So for all the other methods i would then have to precede them with
#pragma unmanaged to ensure they stay native given the module has been
compiled \clr.

The pragma can be a pplied anywhere except inside a class definition.

#pragma unmanaged
class MyClass
{
public:
void MyNativeMethod(); //must be a native function
int i;
...
}

#pragma managed
ref class MyRefClass
{

public:
void MyManagedMethod(); //must be a managed function
int i;

};

In above sample MyNativeMethod will be compiled as native code, the class
instance will be stored in the process heap.
MyManagedMethod will be compiled as managed code and the instance of the
class will end on the GC heap.
This is alot of editing, i just want to do the inverse.
Default to compiling them native unless you hit #pragma managed.

Not sure why you wan't some classes to be unmmanaged while others should be
managed, anyway if you compile your program with /clr without any pragma
unmanaged in the compiland, all code will be compiled to IL, will all data
members an the object instances will be treated as native objects.
And this is what is basically mixed mode.
I dont see the point in #pragma managed if it can only be used within a
module compiled with \clr?

Don't get this one, sorry.


Willy.
 
H

Herby

Thanks Willy.

You know my misunderstanding may be in the use of the #pragma
directive.
Iv not had much need for them in the past, other than now.

#pragma unmanaged
Will remain in effect until until it hits
#pragma managed
within the scope of a module

So if i compile my native class with \clr then the code contained
within the methods will be IL and
within these methods i could create and use managed types.

So i could have

#pragma unmanaged

void MyClass::method1(){
}

void MyClass::method2(){
}

#pragma managed
void MyClass::NewMethod3(){

// Can now access BCL here

String^ str = new String;
}

Correct?




}
 
W

Willy Denoyette [MVP]

Herby said:
Thanks Willy.

You know my misunderstanding may be in the use of the #pragma
directive.
Iv not had much need for them in the past, other than now.

#pragma unmanaged
Will remain in effect until until it hits
#pragma managed
within the scope of a module

So if i compile my native class with \clr then the code contained
within the methods will be IL and
within these methods i could create and use managed types.

So i could have

#pragma unmanaged

void MyClass::method1(){
}

void MyClass::method2(){
}

#pragma managed
void MyClass::NewMethod3(){

// Can now access BCL here

String^ str = new String;
}

Correct?




}

Exactly, but it is not that restrictive though, you can also access non
managed types from managed types or unmanaged types from managed types.

ref class A {
public:
...
void ManagedFunction();
...
private:
MyClass *unm;
}

A::ManagedFunction()
{
unm->method1(); // call your native class function
}


Only thing you can't do is 'embed' mixed types (not yet, maybe in some later
release).

Willy.
 
H

Herby

Thanks Willy.

My specific problem is I want to serialize a parallel .NET object graph
derived from my current MFC objects.
This will then be used in a new .NET application which compiles with
\clr safe
I want to keep the original source application native. Only selectively
using managed code where absolutely necessary.

E.g.

compile UnManagedClass.cpp as \clr

#pragma unmanaged

// All methods here compile to pure native ... As they always were

// Each class participating in the conversion to .NET will implement
the following new method(interface)
// which must be managed for reasons already discussed.
#pragma managed
UnManagedClass::Convert2DotNet( DotNetConversionContext& context )
{
ManagedClass^ pMC = gcnew ManagedClass;
/// set properties on pMc from 'this' native data members
context.Add( pMC );
}

Its only this method i want compiled as managed everything else stays
the same.
So, i do not require mixed type classes as i have no need to maintain
state.
 
R

Ronald Laeremans [MSFT]

Herby said:
Thanks Willy.

My specific problem is I want to serialize a parallel .NET object graph
derived from my current MFC objects.
This will then be used in a new .NET application which compiles with
\clr safe
I want to keep the original source application native. Only selectively
using managed code where absolutely necessary.

E.g.

compile UnManagedClass.cpp as \clr

#pragma unmanaged

// All methods here compile to pure native ... As they always were

// Each class participating in the conversion to .NET will implement
the following new method(interface)
// which must be managed for reasons already discussed.
#pragma managed
UnManagedClass::Convert2DotNet( DotNetConversionContext& context )
{
ManagedClass^ pMC = gcnew ManagedClass;
/// set properties on pMc from 'this' native data members
context.Add( pMC );
}

Its only this method i want compiled as managed everything else stays
the same.
So, i do not require mixed type classes as i have no need to maintain
state.
Hi,

What you said in this thread is correct. #pragma managed has no meaning
in a file not compiled with the /clr switch. The compiler needs to know
ahead of time (before it starts processing the file) that it will
encounter managed blocks since tha implies it needs to generate metadata
. That happens even in #pragma unmanaged blocks.

E.g. in your example the compiler needs metadata (even just the opaque
valuetype definitions it generates for native classes) for class
UnManagedClass in order to generate the method correctly in managed code.

So there is a clear difference between a file that is not compiled /clr
and one that is compiled /clr but has #pragma unmanaged as its first
line: the first does not generate any metadata, the second does.

Ronald Laeremans
Visdual C++ team
 

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