Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen –...

16
Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – [email protected]

Transcript of Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen –...

Page 1: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

Software Engineering in RoboticsInterfacing to external functions

Henrik I. Christensen – [email protected]

Page 2: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

Introduction Motivation – take home messages What is managed code? Interfacing to managed code

Direct DLL interfacing Accessing external libraries

Summary

Page 3: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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, …

Page 4: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 5: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 6: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 7: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 8: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 9: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 10: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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];

Page 11: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 12: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 13: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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();

} }

Page 14: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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();

} }

Page 15: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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

Page 16: Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen – hic@cc.gatech.eduhic@cc.gatech.edu.

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.