Best Practices for Interop

Download Report

Transcript Best Practices for Interop

Best Practices for
Interop with Visual C++
Boris Jabes
Program Manager
Microsoft Corporation
Overview
What is Interop?
Crossing the native (x86) and managed (IL) boundary
Multiple ways to do it
COM Interop, P/Invoke, C++ techniques
This talk will discuss all 3 techniques and both
“directions”
Calling native code from managed code
Calling managed code from native code
Focus on C++
Calling native code via COM
Wrap existing objects into COM components
Can be difficult if unfamiliar with C++ / COM code
Need to deal with lifetime management, identity
management, error handling, correct apartment
and threading transitions
Calling native code via P/Invoke
Easy way to call C-style flat APIs from managed
code
Common candidate is Win32 API
It can be pretty clunky
Imagine not having pinvoke.net!
C++ Interop techniques
Once again, there are many ways to do it
1.
2.
3.
Compiling component with /clr
Writing a wrapper class
Calling native code directly from C++/CLI (aka IJW)
3 flavors of /clr
/clr – produces mixed native/managed binary
/clr:pure – produces a pure (not safe or verifiable)
MSIL binary from C++/CLI. Fully supports ISO C++
/clr:safe – produces a verifiably safe MSIL binary (no
pointers…)
Internal Adapter Method
Problem
How can managed implementations make use of
native types without building additional managed
abstractions?
Important
Reduce marshalling overhead for chatty methods
Maximize reuse of native domain models
Solution
Internal methods with native types as parameters and
return values
Avoid per call marshalling cost
Managed implementation can use native types directly
Holding a native object in a ref type
#include “NativeType.h”
public ref class PublicType
{
NativeType*
_NativePtr;
public:
void PublicMethod()
{ _NativePtr->Method(); }
internal:
void SetNativeType(NativeType* nativePtr);
};
Native P-Impl in Managed Type
Problem
How can a managed API delegate implementation to
an existing native C++ implementation?
Important
Maximize reuse of native implementation
Leverage native performance features
Solution
Use smart pointer to manage lifetime
Delegate as Function Pointer for callback
Using a managed function to respond to a
native callback
#include <NativeType.h>
using Marshal;
typedef void (__stdcall *CBPTR)(int);
delegate void Callback ( int val );
ref class M {
NativeType* _Impl;
Callback^ _Cback;
public:
M() : _Impl(new NativeType()) {
_Cback = gcnew Callback(this,&M::F);
_Impl.SetCallback((CPBTR)
GetFunctionPointerForDelegate(_Cback).ToPointer());
}
private:
void F( int val );
};
Calling managed code from native C++
Visual C++ emphasizes keeping your existing
code and incrementally adding managed
functionality
Your Application Now
Built on top of native libraries
Native Libraries
Compile Pieces
with /clr
New Application with
Added Functionality
Native
Libraries
Managed
Libraries
Using managed libraries in native code
Simplest
/clr on entire project
Add reference to desired dlls (also works for COM)
More granular approach
/clr on the files necessary only
#using <System.Xml.dll> in order to import library
A source file can make use of several kinds of
libraries in a similar fashion
#using
<System.Data.dll> // .NET library
#import <msxml6.dll>
// COM type library
#include <iostream>
// Standard C++ library
Performance
It’s all about reducing transitions
P/Invoke vs. C++ Interop
C++ is faster by default
Common Mistakes I
Marshalling
Blittable types do not require special handling
Try to make marshalling generic and static
(marshal<T>)
Watch out for wide vs. narrow strings
Too many transitions
Wrappers should reduce chattiness
Every transition has a cost, moving the IL boundary
lower can improve performance
Common Mistakes II
Forgetting to manage handles and pointers in
wrapper code
Use auto_gcroot<T>
Write a native equivalent
/clr on everything
DON’T DO IT!!!
#pragma (un)managed!
E.g. good way to reduce transition in tight loops
Additional References
Upcoming book: C++/CLI in action by Nishant
Sivakumar
.NET and COM: The Complete Interoperability
Guide by Adam Nathan
© 2006 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.
The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not
be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation.
MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.