Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen –...
-
Upload
maximilian-campbell -
Category
Documents
-
view
214 -
download
2
Transcript of Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen –...
Software Engineering in RoboticsInterfacing to external functions
Henrik I. Christensen – [email protected]
Introduction Motivation – take home messages What is managed code? Interfacing to managed code
Direct DLL interfacing Accessing external libraries
Summary
C# Process Model
C#Code
CLRnativeCode
JITCompiler
MSILLanguageInterpreter
The MSIL provides facilities for interoperability across languages
Code that is compiled to run through the Common Language Runtime is considered “managed”
CLR support heap management, memory, security, …
The main limitation is lack of access to pointers, …
Managed vs Unmanaged Code Managed code provide security and a harness
to handling exception handling etc. This is achieved through strong typing and
type checking The CLR manages the heap, and does full
checking This can be at the cost of temporal jitter and
inability to manage memory directly Sometimes it make sense to do direct
management or to control timing explicitly. I.e. the programmer takes over responsibility for security, memory management
Such code is term “unsafe” or unmanaged
Why use unmanaged code? Sometimes valuable libraries are available
that you want to leverage without a complete rewrite.
Sometimes you want direct access to a low-level API
Sometimes you need to write a driver with direct management of low level details
Example is for example the OpenCV C++ library
Or access to a hardware interface for a robot controller
Accessing DLL functions Exposing DLL functions to C# runtime
using System;using System.Runtime.InteropServices;class VirtualMemoryManager {
[DllImport(“kernel32.dll”,EntryPoint=“GetCurrentProcess”)]
internal static extern IntPtr GetCurrentProcessHandle();}
The method must be static The Win32 API has inconsistent error handling, so be
aware
Guidelines to code design Made sure the API is not already exposed Define API external methods as private or
internal Provide public wrappers around external code
to handle data conversion and error handling Use enums and consts to make API values Wrap resources such as handles into classes
that derive from System.Runtime.InteropServices.SafeHandle to ensure handling of pointers
Map input/outputs to ref parameters to avoid relying on pointers
Doing unsafe code Sometimes you need unsafe code (say drivers) You can designate a code block to be unsafe
class Program {unsafe static int Main( string[] args ){// …}
} Or class Program {
static int Main( string[] args ){//…unsafe{ // …}//…
}}
Need to compile with the switch /unsafe i.e. csc.exe /unsafe ex.cs
Pointers You can then do regular pointer management
as in C++, C, … byte* pData;
You can only generate pointers to unmanaged types I.e. you cannot do
string* pMessage Memory can move around in a dynamic
environment
Fixed keyword One can “fix”data for a certain amount of
period byte[] bytes = new byte[12];
fixed ( byte* pData = &bytes[0] ) {// process your data with worry of moving
data// ….
} // and now it may moved around again Alternatively you can allocate data on the
stack byte* bytes = stackalloc byte[42];
Think about performance Switch to COM code – 50 cycle overhead Switch to unmanaged code – 10 cycle
overhead Guidelines for code
Made interface chunky and not chatty Avoid ANSI/Unicode conversions For high-performance scenarios, declaring
parameters and fields as IntPtr can boost performance
Use SetLastError=false on platform invoke signatures only if you will call Marshal.GetLastWin32Error afterwards
If, and only if, unmanaged calls are exposed in a non-exploitable fashion, use SuppressUnmanagedCodeSecurityAttribute to reduce the number of security checks
Example for interface to Matlab using System;
using System.Collections.Generic;using System.Windows.Forms;using EngMATLib;using System.Runtime.InteropServices;
namespace Mat_Envelope { static class Program { [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern ushort GlobalAddAtom(string lpString); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern ushort GlobalFindAtom(string lpString); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern ushort GlobalDeleteAtom(ushort atom); [STAThread] static void Main() { string atomStr = Application.ProductName + Application.ProductVersion; ushort Atom = GlobalFindAtom(atomStr); if (Atom > 0) { MessageBox.Show("You are trying to open second instance of the App!"); } else { // The Atom does not exist. Now we need to add it: Atom = GlobalAddAtom(atomStr); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MatEnvelope()); GlobalDeleteAtom(Atom); } } } }
You can get the interface from MATHWORKS – File sharing for running matlab from a C# program
Another example // PInvokeTest.cs (use puts from msvcrt for output)
using System; using System.Runtime.InteropServices; class PlatformInvokeTest {
[DllImport("msvcrt.dll")] public static extern int puts(string c);
[DllImport("msvcrt.dll")] internal static extern int _flushall(); public static void Main() {
puts("Test"); _flushall();
} }
Same example with marshalling // Marshal.cs
using System; using System.Runtime.InteropServices; class PlatformInvokeTest {
[DllImport("msvcrt.dll")] public static extern int puts(
[MarshalAs(UnmanagedType.LPStr)] string m);
[DllImport("msvcrt.dll")] internal static extern int_flushall(); public static void Main() {
puts("Hello World!"); _flushall();
} }
Summary Consider use of external libraries. Do you need to make the switch to mixed
models? There are a few different models Provide good wrappers to isolate risk Think about recommendations to maintain
performance Doing unmanaged code is frequent in robotics
as you need to interface to providers code A good chunky interface will allow you to do this
efficiently
Acknowledgement This series of lectures has been developed
with generous support from the Microsoft Corporation as part of the project “Software Engineering in Robotics” Contract # 113873. The support is gratefully acknowledged.