Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / July 2006

Tip: Looking for answers? Try searching our database.

Using /clr in MFC ATL apps

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Juan Dent - 09 Jul 2006 02:07 GMT
Hi,

I have a large MFC ATL EXE built with C++ 8, and now I am compiling with
/clr to enable C++ interop - i.e. accesing .NET components directly in the
same executable as the unmanaged code from MFC/ATL.

When I compile I get a series of warnings and would like to know if they are
of concern or not and also what they mean. For instance, I don't quite
understand this next warning since CShortcutBarFrame being MFC based it is no
surprise it will be natively compiled:

----------------
warning C4793: 'virtual-call thunks are native with /clr' : causes native
code generation for function 'CShortcutBarFrame::`vcall'{328}''
----------------

Next, I have an #import "xx.tlb" which generates  the next warning. This tlb
is actually generated from an originally all .NET component. My question here
is how should I proceed to use this component from C++/CLI with better
support and performance? My idea is to use #using "xx.dll". What dangers
await me in that road that I could know in advance?

-----------------
warning C4279: 'value': identifier in type library
'Exactus.ORM.Gateway.v1.tlb' is a keyword; use the 'rename' qualifier
-----------------

Finally, and most importantly, how can I find out which parts of my code are
compiled to native and which to MSIL?

Signature

Thanks in advance,

Juan Dent, M.Sc.

"Peter Huang" [MSFT] - 10 Jul 2006 08:42 GMT
Hi Juan,

Thanks for your posting!
I think you may simple put the error code in the MSDN to get the
information.
e.g.
C4793: Error Message
'reason' : causes native code generation for function 'function'
function was compiled to unmanaged, native code, even though the file was
compiled /clr. The compiler will not be able to create an MSIL version of
the function if the function includes setjmp, inline assembly, or a
parameter list that includes a variable number of parameters.
This is a level 1 warning when compiling with /clr:pure.

The warning above generally meansthe function have only the unmanaged
version and is not visible to .NET.

For your second concern, is how to use the .NET assembly in C++/CLR.
My suggestion is to use the #using keyword, because if we use the #import
to import the tlb, then the code is just as we do in the legacy unmanaged
C++. In which we even did no need the /clr switch.
So far,sine your are trying to use /clr and call code with .NET
assembly(MSIL) and pure C++, so I think we did not need to #import the tlb
file.

If you still have any concern, please feel free to post here.

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Juan Dent - 10 Jul 2006 19:29 GMT
Hi,

Thnaks Peter. One thing that was not addressed is how can I know which
functions/classes of my /clr compiled EXE will be managed and which will be
unmanaged?

Signature

Thanks in advance,

Juan Dent, M.Sc.

> Hi Juan,
>
[quoted text clipped - 33 lines]
> ==================================================
> This posting is provided "AS IS" with no warranties, and confers no rights.
"Peter Huang" [MSFT] - 11 Jul 2006 03:59 GMT
Hi Juan,

Thanks for your quickly reply!
I think you may take a look at the good article below.

By throwing the /clr switch, the compiler generates MSIL instead of native
machine code. The only code that is generated as native machine code is
code that just can't be compiled to MSIL, including functions with inline
asm blocks and operations that use CPU-specific intrinsics such as
Streaming SIMD Extensions (SSE).

http://msdn.microsoft.com/msdnmag/issues/04/05/VisualC2005/

Remarks
The /clr compiler option provides module-level control for compiling
functions either as managed or unmanaged.
An unmanaged function will be compiled for the native platform, and
execution of that portion of the program will be passed to the native
platform by the common language runtime.

***Functions are compiled as managed by default when /clr is used.

Use the following guidelines when applying these pragmas:
Add the pragma preceding a function but not within a function body.
Add the pragma after #include statements (do not use these pragmas before
#include statements).
The compiler ignores the managed and unmanaged pragmas if /clr is not used
in the compilation.
When a template function is instantiated, the pragma state at the time of
definition for the template determines if it is managed or unmanaged.
For more information, see Initialization of Mixed Assemblies.
http://msdn2.microsoft.com/en-us/library/0adb9zxe.aspx

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Juan Dent - 12 Jul 2006 01:12 GMT
Hi and thanks again Peter.
One question, if all functions are by default compiled as managed and you
are using MFC/ATL, then there is going to be a lot of changing between
managed and unmanaged which I can only expect will produce a VERY poor
performance.

Is this correct? Or can I NGEN the EXE and get rid of this?
I find when I  compiled the large EXE with /clr, it takes a lot longer to do
anything than if I compile unmanaged.

Again I was looking in /clr a better solution to integrate my EXE with many
.NET components, but I am not sure anymore if this makes sense or I should
remain using COM Interop.

What are your thoughts on that?
Signature

Thanks in advance,

Juan Dent, M.Sc.

> Hi Juan,
>
[quoted text clipped - 39 lines]
> ==================================================
> This posting is provided "AS IS" with no warranties, and confers no rights.
Marcus Heege - 12 Jul 2006 08:10 GMT
I would not recommend to compile the whole project with /clr. Leve
everything as it is and start with a single empty new file compiled with
/clr.

Then, you can define methods in this new file and call them from native
code. This means that your normal program flow (apart from startup and
shutdown) does not need any managed/unmanaged transitions at all.

Marcus Heege

> Hi and thanks again Peter.
> One question, if all functions are by default compiled as managed and you
[quoted text clipped - 60 lines]
>> This posting is provided "AS IS" with no warranties, and confers no
>> rights.
Juan Dent - 12 Jul 2006 18:39 GMT
Hi and thanks.

But even if I create a new file and compile only this file with /clr, then
when I call any function in this file from a function in the other files in
the project (which are not compiled with /clr) that would entail a managed to
unmanaged overhead, am I wrong?

I mean, how is this better performing than simple old COM Interop? (i.e.
placing the managed code in its own assembly and calling functions in it from
the unmanaged EXE via CCW).

Signature

Thanks in advance,

Juan Dent, M.Sc.

> I would not recommend to compile the whole project with /clr. Leve
> everything as it is and start with a single empty new file compiled with
[quoted text clipped - 70 lines]
> >> This posting is provided "AS IS" with no warranties, and confers no
> >> rights.
Marcus Heege - 12 Jul 2006 23:24 GMT
Hi Juan
> Hi and thanks.
>
[quoted text clipped - 4 lines]
> to
> unmanaged overhead, am I wrong?

My point is that you can control very fine-grained how and how often a
managed / unmanaged transition takes place. If you have to call a managed
function very often, you can factor out some code in your old files into the
one compiled with /clr, so that many managed/unmanaged transitions are
replaced by one.

> I mean, how is this better performing than simple old COM Interop? (i.e.
> placing the managed code in its own assembly and calling functions in it
> from
> the unmanaged EXE via CCW).

It usually performs better, because the thunks created from C++/CLI Interop
perform significantly faster. Furthermore, C++/CLI Interop is a two-way
interop
architecture. You can call from managed code to unmanaged code and from
unmanaged code to managed code. At the source code level, the only thing you
need for both directions is a method signature.
   On the other hand, callbacks via COM Interop very likely end up in
Runtime Callable Wrappers being used. Runtime Callable Wrappers are a really
painful construct. Lifetime management can be very difficult (2 ref counts
involved). The worst part about RCWs is that they do not respect the rules
of COM Apartment models.
   Progrmming COM in native C++ can be hard, using COM Interop can add a
significant level of complexity to the whole picture.

>> I would not recommend to compile the whole project with /clr. Leve
>> everything as it is and start with a single empty new file compiled with
[quoted text clipped - 78 lines]
>> >> This posting is provided "AS IS" with no warranties, and confers no
>> >> rights.
"Peter Huang" [MSFT] - 14 Jul 2006 04:21 GMT
Hi Juan,

Thanks for Marcus's input and I agree with Juan's suggestion.
The VC and CLR teams have done lots of performance analysis. But there isn¡
¯t a simple answer to this question. Let me say some basic things
/clr:safe code will generally perform as well or often better than the
equivalent C# code, because the C++ optimizer can make improvements to the
IL. If you take advantage of C++-specific constructs and patterns, these
gains can be larger. But remember that /clr:safe code can¡¯t use native
classes or memory, and so your existing code won¡¯t recompile to safe.
/clr:pure code mixes traditional native classes and managed classes in the
same image, but with ¡°CLR-style defaults¡±. It¡¯s appdomain friendly, and
can benefit from some of the same optimization opportunities as above. Some
traditional code can be recompiled to pure, but pure mode is missing some
things (__stdcall, for example) that stop some libraries you might want to
use (ATL, MFC) from working. This can limit its utility. Calling down to
traditional native library functions (printf, strcpy, etc) involves
thunking as usual.
/clr code mixes traditional native classes and managed classes in the same
image, but with ¡°native-style¡± defaults. It is the only one of these
models that can link in existing native libraries and other native code not
compiled /clr. It is not appdomain friendly (in general), and suffers from
thunking costs in some areas. Thunking was improved a bunch in Whidbey, but
working with /clr code performance is still quite subtle. /clr code can
perform very well, but is likely to require more tuning than the two above.
And there is a tension between the CLR and the native models that comes up
a lot. Since things like vtable slots are native function pointers by
default, you can get a lot of thunking in some scenarios.

Depending on your scenario, you might want to choose one or another of
these models. If you have lots of existing code, you probably need /clr
right now, but this is the one with the most challenges. Our recommendation
in general is for customers to take a large application and recompile
specific files /clr rather than throw /clr on the whole application. This
path is easier to work with in general. And only the source files that need
to work with managed objects or call managed APIs need to be /clr.

Also /CLR is the only option when compiling MFC code. NGEN will not help
with thunking issues, it just saves you JIT'ing costs.
You may start with this sample:
http://www.microsoft.com/downloads/details.aspx?familyid=987021bc-e575-4fe3-
baa9-15aa50b0f599&displaylang=en
It isolates managed code into an extension DLL.

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.