SlideShare a Scribd company logo
1 of 40
Training Material

Rainer Stropek
software architects gmbh

P/Invoke

Web http://www.timecockpit.com
Mail rainer@timecockpit.com
Twitter @rstropek

.NET Interop

Saves the day.
C++ Basics

Interop-related topics for C++
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the PINVOKE_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// PINVOKE_EXPORTS functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef PINVOKE_EXPORTS
#define PINVOKE_API __declspec(dllexport)
#else
#define PINVOKE_API __declspec(dllimport)
#endif

DLL Exports

// Some quite simple functions to begin with
extern "C" PINVOKE_API int AddNumbers(int x, int y);
extern "C" PINVOKE_API int AddArray(int x[], int size);

// A very simple DLL export.
extern "C" PINVOKE_API int AddNumbers(int x, int y)
{
return x + y;
}
// A method taking an array.
extern "C" PINVOKE_API int AddArray(int x[], int size)
{
auto ans = 0;
for (int i = 0; i < size; i++)
{
ans += x[i];
}
return ans;
}
See also MSDN
dumpbin
Get list of exports of an
unmanaged DLL
Parameters
/imports
/exports

See MSDN for details
Memory Handling
 Native

DLL should avoid allocating memory and expect the
caller to free the memory

 Use

CoTaskMemAlloc instead of new

Freed by Interop Marshaller of .NET automatically using CoTaskMemFree
Can be freed manually using Marshal.FreeCoTaskMem

 Native

DLL could offer a function to free the memory

See CMiniVan example (CreateMiniVan and DeleteMiniVan)
Debugging
Enable native code
debugging

Step into unmanaged code
Interop Basics
Interop Basics
 System.Runtime.InteropServices

Namespace

 System.Runtime.InteropServices.Marshal
Important helper methods for working with unmanaged code

class

 System.Runtime.InteropServices.DllImportAttribute
Import a method from an unmanaged DLL
Data Type Mapping
See also MSDN
More detailed list can be
found in Nathan, .NET
and COM, 779ff

Source: Troelsen, COM and .NET Interoperability
Marshal Class

For details see MSDN
DllImportAttribute
DllImportAttribute
 Calling

convention

 Character

set

 Entry

point

 Exact

spelling

 Error

handling

Can be used to rename functions

Controls whether character set is used to look for entry point name

SetLastError behavior
Calling Conventions
 See

also MSDN article about calling conventions

By default, VC++ uses _cdecl

 P/Invoke

behavior has changed in .NET 4

In .NET < 4 you could call a _cdecl function with __stdcall without any problems
In .NET >= 4 you will get an exception in the debugger
See also pInvokeStackImbalance and NetFx40_PInvokeStackResilience

See also http://blogs.msdn.com/b/oldnewthing/archive/2004/01/08/48616.aspx
// This works
extern "C" PINVOKE_API int __stdcall AddNumbers(int x, int y);
[DllImport("PInvokeIntroduction.dll")]
public static extern int AddNumbers(int x, int y);

// This works, too
extern "C" PINVOKE_API int AddNumbers(int x, int y);
[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl)]
public static extern int AddNumbers(int x, int y);

// Anything else will throw an exception in the debugger

Calling Conventions
Marshal Strings
 Character

sets

Ansi
Unicode
Auto (depends on operating system type)
None (obsolete)

 Specify

character set

In DllImportAttribute
In MarshalAsAttribute
using System.Runtime.InteropServices;
namespace Samples.PInvoke.IntroductionClient
{
[StructLayout(LayoutKind.Sequential)]
public class Car
{
[MarshalAs(UnmanagedType.LPWStr)]
public string Make;

Character Sets

[MarshalAs(UnmanagedType.LPWStr)]
public string Color;

}
…
}

[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode)]
public static extern void DisplayBetterCar(Car2 c);

See also MSDN
// Rename the MessageBoxW() function to 'DisplayMessage'.
[DllImport("user32.dll",
ExactSpelling = true,
CharSet = CharSet.Unicode,
EntryPoint = "MessageBoxW")]
public static extern int DisplayMessage(int hwnd, string text,
string caption, int type);

Renaming Method
// Note that we pass an invalid window handle
// to MessageBox  error
PInvokeWrapper.DisplayMessage(999, "Hello World!", "Greeting",
0);
Console.WriteLine("Last Win32 Error: {0}",
Marshal.GetLastWin32Error());
Console.WriteLine(new Win32Exception(
Marshal.GetLastWin32Error()).Message);

Win32 Errors
LayoutKind




Necessary when marshalling structure

Note that you can marshal structures as C# structs or classes

LayoutKind.Sequential

Recommendation for structure marshalling
Order of the fields is preserved



LayoutKind.Explicit

Manually calculate the physical position of fields
Combined with FieldOffsetAttribute
Use FieldOffsetAttribute for implementing unions, too



LayoutKind.Auto

Not used for P/Invoke as C# compiler could change the order of the fields
using System.Runtime.InteropServices;
namespace Samples.PInvoke.IntroductionClient
{
[StructLayout(LayoutKind.Sequential)]
public class Car
{
public string Make;
public string Color;
}
// A structure containing another structure.
[StructLayout(LayoutKind.Sequential)]
public class Car2
{
public Car Car = new Car();
public string PetName;
}

}

StructLayout
// A Method returning an array of structs.
extern "C" PINVOKE_API void GiveMeThreeBasicCars(CAR** theCars)
{
auto numbOfCars = 3;
// Use CoTaskMemAlloc instead of new as .NET's P/Invoke uses
// CoTaskMemFree. See also http://blogs.msdn.com/b/dsvc/archive/2009/06/22/troubleshooting-pinvoke-related-issues.aspx
// and http://stackoverflow.com/questions/3614367/c-sharp-free-memory-allocated-by-operator-new-from-p-invoke-dll
// for details.
*theCars = (CAR*)CoTaskMemAlloc(numbOfCars * sizeof(CAR));
LPSTR carMakes[3] = { "BMW", "Ford", "Viper" };
LPSTR carColors[3] = { "Green", "Pink", "Red" };
auto pCurCar = *theCars;
for (int i = 0; i < numbOfCars; i++, pCurCar++)
{
pCurCar->color = carColors[i];
pCurCar->make = carMakes[i];
}
}

[DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void GiveMeThreeBasicCars(out IntPtr theCars);
public static IEnumerable<Car> GiveMeThreeBasicCarsHelper() {
const int size = 3;
var result = new List<Car>(size);
// Pass in an IntPtr as an output parameter.
IntPtr outArray;
PInvokeWrapper.GiveMeThreeBasicCars(out outArray);
try {
// Helper for iterating over array elements
IntPtr current = outArray;
for (int i = 0; i < size; i++) {
// Get next car using Marshal.PtrToStructure()
var car = Marshal.PtrToStructure<Car>(current);
result.Add(car);
// Calculate location of next structure using Marshal.SizeOf().
current = (IntPtr)((int)current + Marshal.SizeOf<Car>());
}
}
finally {
// Free memory for the allocated array.
Marshal.FreeCoTaskMem(outArray);
}
return result;
}

Marshal an Array
#include "stdafx.h"
// A class to be exported.
class PINVOKE_API CMiniVan
{
private:
int m_numbSeats;
public:
CMiniVan()
{
m_numbSeats = 9;
}
int GetNumberOfSeats()
{
return m_numbSeats;
}

};
// Functions for class
extern "C" PINVOKE_API
extern "C" PINVOKE_API
extern "C" PINVOKE_API

marshaling.
CMiniVan* CreateMiniVan();
void DeleteMiniVan(CMiniVan* obj);
int GetNumberOfSeats(CMiniVan* obj);

Marshalling Classes
// extern "C" PINVOKE_API CMiniVan* CreateMiniVan();
[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr CreateMiniVan();
// extern "C" PINVOKE_API void DeleteMiniVan(CMiniVan* obj);
[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl)]
public static extern void DeleteMiniVan(IntPtr miniVan);
// extern "C" PINVOKE_API int GetNumberOfSeats(CMiniVan* obj);
[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl)]
public static extern int GetNumberOfSeats(IntPtr miniVan);

var miniVan = PInvokeWrapper.CreateMiniVan();
try
{
Console.WriteLine(PInvokeWrapper.GetNumberOfSeats(miniVan));
}
finally
{
PInvokeWrapper.DeleteMiniVan(miniVan);
}

Marshalling Classes
typedef void (CALLBACK *SAYHELLOCALLBACK)();
extern "C" PINVOKE_API void CallMeBackToSayHello(
SAYHELLOCALLBACK callback);
[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl)]
public static extern void CallMeBackToSayHello(
Action callback);

Marshalling Callbacks
typedef struct
{
double a;
double b;
double c;
} TRIANGLE;
typedef void (CALLBACK *PYTHAGORASCALLBACK)(TRIANGLE result);
extern "C" PINVOKE_API void ReportPythagorasBack(
double a, double b, PYTHAGORASCALLBACK callback);

[StructLayout(LayoutKind.Sequential)]
public struct Triangle
{
public double a;
public double b;
public double c;
}
public delegate void TriangleCallback(Triangle t);
[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl)]
public static extern void ReportPythagorasBack(
double a, double b, TriangleCallback callback);

Marshalling Callbacks
Unsafe C#
Unsafe C#
 Use

unsafe keyword

Used with type or member
Unsafe code block

 Adds

pointer arithmetic to C#

Similar to C#

 Unsafe

does not mean less safe than normal C#

If you use IntPtr, you are not safer
In both scenarios, C# does not do any checks for buffer overruns

 You

can program P/Invoke without unsafe

Use IntPtr and methods of the Marshal class instead
type *identifier;
void *identifier;// Ptr to unknown type

int* pNumber;
int** ppNumber;
int*[] pArray;

// Ptr to a ptr to int
// Array of int*

int* pNumber
Console.WriteLine(*pNumber);
// Get value that pNumber points to

Pointers in C#
Supported types

sbyte, byte, short, ushort, int, uint,
long, ulong, char, float, double,
decimal, or bool.
Enums
Pointers
User-defined structs with
unmanaged types
namespace FixedSizeBuffers
{
internal unsafe struct MyBuffer
{
public fixed char fixedBuffer[128];
}
internal unsafe class MyClass
{
public MyBuffer myBuffer = default(MyBuffer);
}
internal class Program
{
static void Main()
{
MyClass myC = new MyClass();
unsafe
{
// Pin the buffer to a fixed location in memory.
fixed (char* charPtr = myC.myBuffer.fixedBuffer)
{
*charPtr = 'A';
}
}
}
}
}

Fixed size buffers
Buffer with fixed size

Typically used inside a struct

Supported data types

bool, byte, char, short, int, long,
sbyte, ushort, uint, ulong, float,
or double
Marshalling Details
Tipps & Tricks
 BOOL

can be marshalled to System.Int32 or bool

Marshalling to bool is a little bit slower but convenient
See MSDN for details

 InAttribute

and OutAttribute

By default, direction attribute for non-blittable types is In (performance reasons)
Best practice: Specify [In, Out] for input and output parameters (even for blittable types)
Exception: StringBuilder (In, Out by default)
See also sample in MSDN
Memory Management
 Marshaler

always attempts to free memory allocated by
unmanaged code

Use IntPtr to prevent this

 Memory

is always freed using CoTaskMemFree

Library has to provide a dedicated free method if allocated differently

 See

MSDN for details about copying/pinning

See MSDN for details
String Marshalling
 System.String

for constant strings

LPCSTR, LPCWSTR, etc.

 System.Text.StringBuilder

for string buffers that can change

LPSTR, LPWSTR, etc.
Always initialize size of the StringBuilder (constructor, Capacity property)
StringBuilder are guaranteed to have a terminating null character

 Use

IntPtr and Marshal.PtrToStringXXX if caller should not
free the memory
String Marshalling
 Use

[MarshalAs(UnmanagedType.ByValXXX,
SizeConst=XXX)] for fixed size char buffers

 See

MSDN for details
public
{
//
//
//

static class StringIntPtrHandling
Note that GetPrivateProfileSectionNames returns a string with embedded NULL characters.
See http://msdn.microsoft.com/en-us/library/windows/desktop/ms724352(v=vs.85).aspx
for details.

[DllImport("kernel32.dll")]
static extern int GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, int nSize, string lpFileName);
public static void ExecuteSample()
{
IntPtr ptr = IntPtr.Zero;
string s = string.Empty;
try
{
// Allocate a buffer in unmanaged memory
ptr = Marshal.AllocHGlobal(1024);
// Call Kernel API
var numChars = GetPrivateProfileSectionNames(
ptr,
1024,
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Sample.ini"));
// Copy the buffer into a managed string
s = Marshal.PtrToStringAnsi(ptr, numChars - 1);
}
finally
{
// Free the unmanaged buffer
if (ptr != IntPtr.Zero)
{
Marshal.FreeHGlobal(ptr);
}
}
// Display the sections by splitting the string based on NULL characters
foreach (var section in s.Split('0'))
{
Console.WriteLine(section);
}

}
}

Strings and IntPtr
typedef struct
{
// Note that this structure contains an array of characters
char make[256];
char color[256];
} CARFIXED;
extern "C" PINVOKE_API void FillThreeBasicCars(CARFIXED* theCars);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CarStruct
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string Make;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string Color;
}
[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void FillThreeBasicCars(
[In, Out, MarshalAs(UnmanagedType.LPArray)] CarStruct[] theCars);

Marshalling Arrays
extern "C" PINVOKE_API void GiveMeMakes(BSTR** makes, int *length);

[DllImport("PInvokeIntroduction.dll",
CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern void GiveMeMakes(
[Out, MarshalAs(UnmanagedType.LPArray,
ArraySubType = UnmanagedType.BStr,
SizeParamIndex = 1)] out string[] makes,
[Out] out int length);

Marshalling Arrays
Training Material

Rainer Stropek
software architects gmbh

Q&A

Mail rainer@timecockpit.com
Web http://www.timecockpit.com
Twitter @rstropek

Thank your for coming!
Saves the day.
is the leading time tracking solution for knowledge workers.
Graphical time tracking calendar, automatic tracking of your work using
signal trackers, high level of extensibility and customizability, full support to
work offline, and SaaS deployment model make it the optimal choice
especially in the IT consulting business.
Try
for free and without any risk. You can get your trial account
at http://www.timecockpit.com. After the trial period you can use
for only 0,20€ per user and day without a minimal subscription time and
without a minimal number of users.
ist die führende Projektzeiterfassung für Knowledge Worker.
Grafischer Zeitbuchungskalender, automatische Tätigkeitsaufzeichnung über
Signal Tracker, umfassende Erweiterbarkeit und Anpassbarkeit, volle
Offlinefähigkeit und einfachste Verwendung durch SaaS machen es zur
Optimalen Lösung auch speziell im IT-Umfeld.
Probieren Sie
kostenlos und ohne Risiko einfach aus. Einen
Testzugang erhalten Sie unter http://www.timecockpit.com. Danach nutzen
Sie
um nur 0,20€ pro Benutzer und Tag ohne Mindestdauer
und ohne Mindestbenutzeranzahl.

More Related Content

What's hot

Cling the llvm based interpreter
Cling the llvm based interpreterCling the llvm based interpreter
Cling the llvm based interpreterRoberto Nogueira
 
Aae oop xp_07
Aae oop xp_07Aae oop xp_07
Aae oop xp_07Niit Care
 
Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2ppd1961
 
(7) cpp abstractions inheritance_part_ii
(7) cpp abstractions inheritance_part_ii(7) cpp abstractions inheritance_part_ii
(7) cpp abstractions inheritance_part_iiNico Ludwig
 
Adding Love to an API (or How to Expose C++ in Unity)
Adding Love to an API (or How to Expose C++ in Unity)Adding Love to an API (or How to Expose C++ in Unity)
Adding Love to an API (or How to Expose C++ in Unity)Unity Technologies
 
SoCal Code Camp 2015: An introduction to Java 8
SoCal Code Camp 2015: An introduction to Java 8SoCal Code Camp 2015: An introduction to Java 8
SoCal Code Camp 2015: An introduction to Java 8Chaitanya Ganoo
 
Review: Apitrace and Vogl
Review: Apitrace and VoglReview: Apitrace and Vogl
Review: Apitrace and VoglGao Yunzhong
 
Checking the Source Code of FlashDevelop with PVS-Studio
Checking the Source Code of FlashDevelop with PVS-StudioChecking the Source Code of FlashDevelop with PVS-Studio
Checking the Source Code of FlashDevelop with PVS-StudioPVS-Studio
 
Handling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVMHandling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVMMin-Yih Hsu
 
"Why is there no artificial intelligence yet?" Or, analysis of CNTK tool kit ...
"Why is there no artificial intelligence yet?" Or, analysis of CNTK tool kit ..."Why is there no artificial intelligence yet?" Or, analysis of CNTK tool kit ...
"Why is there no artificial intelligence yet?" Or, analysis of CNTK tool kit ...PVS-Studio
 
HKG15-207: Advanced Toolchain Usage Part 3
HKG15-207: Advanced Toolchain Usage Part 3HKG15-207: Advanced Toolchain Usage Part 3
HKG15-207: Advanced Toolchain Usage Part 3Linaro
 
How to capture a variable in C# and not to shoot yourself in the foot
How to capture a variable in C# and not to shoot yourself in the footHow to capture a variable in C# and not to shoot yourself in the foot
How to capture a variable in C# and not to shoot yourself in the footSofia Fateeva
 
Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016PVS-Studio
 

What's hot (20)

Managed Compiler
Managed CompilerManaged Compiler
Managed Compiler
 
Cling the llvm based interpreter
Cling the llvm based interpreterCling the llvm based interpreter
Cling the llvm based interpreter
 
C Language Unit-1
C Language Unit-1C Language Unit-1
C Language Unit-1
 
Plsql pdf
Plsql pdfPlsql pdf
Plsql pdf
 
Oop Presentation
Oop PresentationOop Presentation
Oop Presentation
 
Aae oop xp_07
Aae oop xp_07Aae oop xp_07
Aae oop xp_07
 
Project Roslyn: Exposing the C# and VB compiler’s code analysis
Project Roslyn: Exposing the C# and VB compiler’s code analysisProject Roslyn: Exposing the C# and VB compiler’s code analysis
Project Roslyn: Exposing the C# and VB compiler’s code analysis
 
Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2
 
(7) cpp abstractions inheritance_part_ii
(7) cpp abstractions inheritance_part_ii(7) cpp abstractions inheritance_part_ii
(7) cpp abstractions inheritance_part_ii
 
Adding Love to an API (or How to Expose C++ in Unity)
Adding Love to an API (or How to Expose C++ in Unity)Adding Love to an API (or How to Expose C++ in Unity)
Adding Love to an API (or How to Expose C++ in Unity)
 
SoCal Code Camp 2015: An introduction to Java 8
SoCal Code Camp 2015: An introduction to Java 8SoCal Code Camp 2015: An introduction to Java 8
SoCal Code Camp 2015: An introduction to Java 8
 
C tutorial
C tutorialC tutorial
C tutorial
 
Aptitute question papers in c
Aptitute question papers in cAptitute question papers in c
Aptitute question papers in c
 
Review: Apitrace and Vogl
Review: Apitrace and VoglReview: Apitrace and Vogl
Review: Apitrace and Vogl
 
Checking the Source Code of FlashDevelop with PVS-Studio
Checking the Source Code of FlashDevelop with PVS-StudioChecking the Source Code of FlashDevelop with PVS-Studio
Checking the Source Code of FlashDevelop with PVS-Studio
 
Handling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVMHandling inline assembly in Clang and LLVM
Handling inline assembly in Clang and LLVM
 
"Why is there no artificial intelligence yet?" Or, analysis of CNTK tool kit ...
"Why is there no artificial intelligence yet?" Or, analysis of CNTK tool kit ..."Why is there no artificial intelligence yet?" Or, analysis of CNTK tool kit ...
"Why is there no artificial intelligence yet?" Or, analysis of CNTK tool kit ...
 
HKG15-207: Advanced Toolchain Usage Part 3
HKG15-207: Advanced Toolchain Usage Part 3HKG15-207: Advanced Toolchain Usage Part 3
HKG15-207: Advanced Toolchain Usage Part 3
 
How to capture a variable in C# and not to shoot yourself in the foot
How to capture a variable in C# and not to shoot yourself in the footHow to capture a variable in C# and not to shoot yourself in the foot
How to capture a variable in C# and not to shoot yourself in the foot
 
Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016
 

Viewers also liked

WPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaWPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaRainer Stropek
 
Parallel and Async Programming With C#
Parallel and Async Programming With C#Parallel and Async Programming With C#
Parallel and Async Programming With C#Rainer Stropek
 
Agile and Scrum Workshop
Agile and Scrum WorkshopAgile and Scrum Workshop
Agile and Scrum WorkshopRainer Stropek
 
Whats New in Visual Studio 2012 for C++ Developers
Whats New in Visual Studio 2012 for C++ DevelopersWhats New in Visual Studio 2012 for C++ Developers
Whats New in Visual Studio 2012 for C++ DevelopersRainer Stropek
 
Coding Like the Wind - Tips and Tricks for the Microsoft Visual Studio 2012 C...
Coding Like the Wind - Tips and Tricks for the Microsoft Visual Studio 2012 C...Coding Like the Wind - Tips and Tricks for the Microsoft Visual Studio 2012 C...
Coding Like the Wind - Tips and Tricks for the Microsoft Visual Studio 2012 C...Rainer Stropek
 
SaaS, Multi-Tenancy and Cloud Computing
SaaS, Multi-Tenancy and Cloud ComputingSaaS, Multi-Tenancy and Cloud Computing
SaaS, Multi-Tenancy and Cloud ComputingRainer Stropek
 
Business Model Evolution - Why The Journey To SaaS Makes Sense
Business Model Evolution - Why The Journey To SaaS Makes SenseBusiness Model Evolution - Why The Journey To SaaS Makes Sense
Business Model Evolution - Why The Journey To SaaS Makes SenseRainer Stropek
 
Programming With WinRT And Windows8
Programming With WinRT And Windows8Programming With WinRT And Windows8
Programming With WinRT And Windows8Rainer Stropek
 
Michael Kiener Associates Ltd
Michael Kiener Associates LtdMichael Kiener Associates Ltd
Michael Kiener Associates LtdMichaelKiener
 
Telerik Kendo UI vs. AngularJS
Telerik Kendo UI vs. AngularJSTelerik Kendo UI vs. AngularJS
Telerik Kendo UI vs. AngularJSRainer Stropek
 
Cloud computing was bringt's
Cloud computing   was bringt'sCloud computing   was bringt's
Cloud computing was bringt'sRainer Stropek
 

Viewers also liked (14)

WPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA AustriaWPF and Prism 4.1 Workshop at BASTA Austria
WPF and Prism 4.1 Workshop at BASTA Austria
 
Parallel and Async Programming With C#
Parallel and Async Programming With C#Parallel and Async Programming With C#
Parallel and Async Programming With C#
 
Agile and Scrum Workshop
Agile and Scrum WorkshopAgile and Scrum Workshop
Agile and Scrum Workshop
 
Whats New in Visual Studio 2012 for C++ Developers
Whats New in Visual Studio 2012 for C++ DevelopersWhats New in Visual Studio 2012 for C++ Developers
Whats New in Visual Studio 2012 for C++ Developers
 
Coding Like the Wind - Tips and Tricks for the Microsoft Visual Studio 2012 C...
Coding Like the Wind - Tips and Tricks for the Microsoft Visual Studio 2012 C...Coding Like the Wind - Tips and Tricks for the Microsoft Visual Studio 2012 C...
Coding Like the Wind - Tips and Tricks for the Microsoft Visual Studio 2012 C...
 
SaaS, Multi-Tenancy and Cloud Computing
SaaS, Multi-Tenancy and Cloud ComputingSaaS, Multi-Tenancy and Cloud Computing
SaaS, Multi-Tenancy and Cloud Computing
 
The CoFX Data Model
The CoFX Data ModelThe CoFX Data Model
The CoFX Data Model
 
Business Model Evolution - Why The Journey To SaaS Makes Sense
Business Model Evolution - Why The Journey To SaaS Makes SenseBusiness Model Evolution - Why The Journey To SaaS Makes Sense
Business Model Evolution - Why The Journey To SaaS Makes Sense
 
Programming With WinRT And Windows8
Programming With WinRT And Windows8Programming With WinRT And Windows8
Programming With WinRT And Windows8
 
Michael Kiener Associates Ltd
Michael Kiener Associates LtdMichael Kiener Associates Ltd
Michael Kiener Associates Ltd
 
Vertaalbureau Perfect
Vertaalbureau PerfectVertaalbureau Perfect
Vertaalbureau Perfect
 
Telerik Kendo UI vs. AngularJS
Telerik Kendo UI vs. AngularJSTelerik Kendo UI vs. AngularJS
Telerik Kendo UI vs. AngularJS
 
Sculptura in coaja de ou
Sculptura in coaja de ouSculptura in coaja de ou
Sculptura in coaja de ou
 
Cloud computing was bringt's
Cloud computing   was bringt'sCloud computing   was bringt's
Cloud computing was bringt's
 

Similar to P/Invoke - Interoperability of C++ and C#

20145-5SumII_CSC407_assign1.htmlCSC 407 Computer Systems II.docx
20145-5SumII_CSC407_assign1.htmlCSC 407 Computer Systems II.docx20145-5SumII_CSC407_assign1.htmlCSC 407 Computer Systems II.docx
20145-5SumII_CSC407_assign1.htmlCSC 407 Computer Systems II.docxeugeniadean34240
 
DLL Design with Building Blocks
DLL Design with Building BlocksDLL Design with Building Blocks
DLL Design with Building BlocksMax Kleiner
 
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17LogeekNightUkraine
 
CSharp Presentation
CSharp PresentationCSharp Presentation
CSharp PresentationVishwa Mohan
 
data Structure Lecture 1
data Structure Lecture 1data Structure Lecture 1
data Structure Lecture 1Teksify
 
embeddedc-lecture1-160404055102.pptx
embeddedc-lecture1-160404055102.pptxembeddedc-lecture1-160404055102.pptx
embeddedc-lecture1-160404055102.pptxsangeetaSS
 
01 Introduction to programming
01 Introduction to programming01 Introduction to programming
01 Introduction to programmingmaznabili
 
introduction of c langauge(I unit)
introduction of c langauge(I unit)introduction of c langauge(I unit)
introduction of c langauge(I unit)Prashant Sharma
 

Similar to P/Invoke - Interoperability of C++ and C# (20)

Srgoc dotnet_new
Srgoc dotnet_newSrgoc dotnet_new
Srgoc dotnet_new
 
20145-5SumII_CSC407_assign1.htmlCSC 407 Computer Systems II.docx
20145-5SumII_CSC407_assign1.htmlCSC 407 Computer Systems II.docx20145-5SumII_CSC407_assign1.htmlCSC 407 Computer Systems II.docx
20145-5SumII_CSC407_assign1.htmlCSC 407 Computer Systems II.docx
 
C# Unit 2 notes
C# Unit 2 notesC# Unit 2 notes
C# Unit 2 notes
 
srgoc
srgocsrgoc
srgoc
 
DLL Design with Building Blocks
DLL Design with Building BlocksDLL Design with Building Blocks
DLL Design with Building Blocks
 
Srgoc dotnet
Srgoc dotnetSrgoc dotnet
Srgoc dotnet
 
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
 
CSharp Presentation
CSharp PresentationCSharp Presentation
CSharp Presentation
 
data Structure Lecture 1
data Structure Lecture 1data Structure Lecture 1
data Structure Lecture 1
 
Embedded C - Lecture 1
Embedded C - Lecture 1Embedded C - Lecture 1
Embedded C - Lecture 1
 
Csharp dot net
Csharp dot netCsharp dot net
Csharp dot net
 
C Programming Tutorial - www.infomtec.com
C Programming Tutorial - www.infomtec.comC Programming Tutorial - www.infomtec.com
C Programming Tutorial - www.infomtec.com
 
embeddedc-lecture1-160404055102.pptx
embeddedc-lecture1-160404055102.pptxembeddedc-lecture1-160404055102.pptx
embeddedc-lecture1-160404055102.pptx
 
CP Handout#2
CP Handout#2CP Handout#2
CP Handout#2
 
.NET for hackers
.NET for hackers.NET for hackers
.NET for hackers
 
C# tutorial
C# tutorialC# tutorial
C# tutorial
 
Csharp
CsharpCsharp
Csharp
 
01 Introduction to programming
01 Introduction to programming01 Introduction to programming
01 Introduction to programming
 
introduction of c langauge(I unit)
introduction of c langauge(I unit)introduction of c langauge(I unit)
introduction of c langauge(I unit)
 
C# Unit 1 notes
C# Unit 1 notesC# Unit 1 notes
C# Unit 1 notes
 

Recently uploaded

Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 

Recently uploaded (20)

Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 

P/Invoke - Interoperability of C++ and C#

  • 1. Training Material Rainer Stropek software architects gmbh P/Invoke Web http://www.timecockpit.com Mail rainer@timecockpit.com Twitter @rstropek .NET Interop Saves the day.
  • 3. // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the PINVOKE_EXPORTS // symbol defined on the command line. This symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // PINVOKE_EXPORTS functions as being imported from a DLL, whereas this DLL sees symbols // defined with this macro as being exported. #ifdef PINVOKE_EXPORTS #define PINVOKE_API __declspec(dllexport) #else #define PINVOKE_API __declspec(dllimport) #endif DLL Exports // Some quite simple functions to begin with extern "C" PINVOKE_API int AddNumbers(int x, int y); extern "C" PINVOKE_API int AddArray(int x[], int size); // A very simple DLL export. extern "C" PINVOKE_API int AddNumbers(int x, int y) { return x + y; } // A method taking an array. extern "C" PINVOKE_API int AddArray(int x[], int size) { auto ans = 0; for (int i = 0; i < size; i++) { ans += x[i]; } return ans; } See also MSDN
  • 4. dumpbin Get list of exports of an unmanaged DLL Parameters /imports /exports See MSDN for details
  • 5. Memory Handling  Native DLL should avoid allocating memory and expect the caller to free the memory  Use CoTaskMemAlloc instead of new Freed by Interop Marshaller of .NET automatically using CoTaskMemFree Can be freed manually using Marshal.FreeCoTaskMem  Native DLL could offer a function to free the memory See CMiniVan example (CreateMiniVan and DeleteMiniVan)
  • 8. Interop Basics  System.Runtime.InteropServices Namespace  System.Runtime.InteropServices.Marshal Important helper methods for working with unmanaged code class  System.Runtime.InteropServices.DllImportAttribute Import a method from an unmanaged DLL
  • 9. Data Type Mapping See also MSDN More detailed list can be found in Nathan, .NET and COM, 779ff Source: Troelsen, COM and .NET Interoperability
  • 12. DllImportAttribute  Calling convention  Character set  Entry point  Exact spelling  Error handling Can be used to rename functions Controls whether character set is used to look for entry point name SetLastError behavior
  • 13. Calling Conventions  See also MSDN article about calling conventions By default, VC++ uses _cdecl  P/Invoke behavior has changed in .NET 4 In .NET < 4 you could call a _cdecl function with __stdcall without any problems In .NET >= 4 you will get an exception in the debugger See also pInvokeStackImbalance and NetFx40_PInvokeStackResilience See also http://blogs.msdn.com/b/oldnewthing/archive/2004/01/08/48616.aspx
  • 14. // This works extern "C" PINVOKE_API int __stdcall AddNumbers(int x, int y); [DllImport("PInvokeIntroduction.dll")] public static extern int AddNumbers(int x, int y); // This works, too extern "C" PINVOKE_API int AddNumbers(int x, int y); [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int AddNumbers(int x, int y); // Anything else will throw an exception in the debugger Calling Conventions
  • 15. Marshal Strings  Character sets Ansi Unicode Auto (depends on operating system type) None (obsolete)  Specify character set In DllImportAttribute In MarshalAsAttribute
  • 16. using System.Runtime.InteropServices; namespace Samples.PInvoke.IntroductionClient { [StructLayout(LayoutKind.Sequential)] public class Car { [MarshalAs(UnmanagedType.LPWStr)] public string Make; Character Sets [MarshalAs(UnmanagedType.LPWStr)] public string Color; } … } [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public static extern void DisplayBetterCar(Car2 c); See also MSDN
  • 17. // Rename the MessageBoxW() function to 'DisplayMessage'. [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Unicode, EntryPoint = "MessageBoxW")] public static extern int DisplayMessage(int hwnd, string text, string caption, int type); Renaming Method
  • 18. // Note that we pass an invalid window handle // to MessageBox  error PInvokeWrapper.DisplayMessage(999, "Hello World!", "Greeting", 0); Console.WriteLine("Last Win32 Error: {0}", Marshal.GetLastWin32Error()); Console.WriteLine(new Win32Exception( Marshal.GetLastWin32Error()).Message); Win32 Errors
  • 19. LayoutKind   Necessary when marshalling structure Note that you can marshal structures as C# structs or classes LayoutKind.Sequential Recommendation for structure marshalling Order of the fields is preserved  LayoutKind.Explicit Manually calculate the physical position of fields Combined with FieldOffsetAttribute Use FieldOffsetAttribute for implementing unions, too  LayoutKind.Auto Not used for P/Invoke as C# compiler could change the order of the fields
  • 20. using System.Runtime.InteropServices; namespace Samples.PInvoke.IntroductionClient { [StructLayout(LayoutKind.Sequential)] public class Car { public string Make; public string Color; } // A structure containing another structure. [StructLayout(LayoutKind.Sequential)] public class Car2 { public Car Car = new Car(); public string PetName; } } StructLayout
  • 21. // A Method returning an array of structs. extern "C" PINVOKE_API void GiveMeThreeBasicCars(CAR** theCars) { auto numbOfCars = 3; // Use CoTaskMemAlloc instead of new as .NET's P/Invoke uses // CoTaskMemFree. See also http://blogs.msdn.com/b/dsvc/archive/2009/06/22/troubleshooting-pinvoke-related-issues.aspx // and http://stackoverflow.com/questions/3614367/c-sharp-free-memory-allocated-by-operator-new-from-p-invoke-dll // for details. *theCars = (CAR*)CoTaskMemAlloc(numbOfCars * sizeof(CAR)); LPSTR carMakes[3] = { "BMW", "Ford", "Viper" }; LPSTR carColors[3] = { "Green", "Pink", "Red" }; auto pCurCar = *theCars; for (int i = 0; i < numbOfCars; i++, pCurCar++) { pCurCar->color = carColors[i]; pCurCar->make = carMakes[i]; } } [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern void GiveMeThreeBasicCars(out IntPtr theCars); public static IEnumerable<Car> GiveMeThreeBasicCarsHelper() { const int size = 3; var result = new List<Car>(size); // Pass in an IntPtr as an output parameter. IntPtr outArray; PInvokeWrapper.GiveMeThreeBasicCars(out outArray); try { // Helper for iterating over array elements IntPtr current = outArray; for (int i = 0; i < size; i++) { // Get next car using Marshal.PtrToStructure() var car = Marshal.PtrToStructure<Car>(current); result.Add(car); // Calculate location of next structure using Marshal.SizeOf(). current = (IntPtr)((int)current + Marshal.SizeOf<Car>()); } } finally { // Free memory for the allocated array. Marshal.FreeCoTaskMem(outArray); } return result; } Marshal an Array
  • 22. #include "stdafx.h" // A class to be exported. class PINVOKE_API CMiniVan { private: int m_numbSeats; public: CMiniVan() { m_numbSeats = 9; } int GetNumberOfSeats() { return m_numbSeats; } }; // Functions for class extern "C" PINVOKE_API extern "C" PINVOKE_API extern "C" PINVOKE_API marshaling. CMiniVan* CreateMiniVan(); void DeleteMiniVan(CMiniVan* obj); int GetNumberOfSeats(CMiniVan* obj); Marshalling Classes
  • 23. // extern "C" PINVOKE_API CMiniVan* CreateMiniVan(); [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr CreateMiniVan(); // extern "C" PINVOKE_API void DeleteMiniVan(CMiniVan* obj); [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void DeleteMiniVan(IntPtr miniVan); // extern "C" PINVOKE_API int GetNumberOfSeats(CMiniVan* obj); [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int GetNumberOfSeats(IntPtr miniVan); var miniVan = PInvokeWrapper.CreateMiniVan(); try { Console.WriteLine(PInvokeWrapper.GetNumberOfSeats(miniVan)); } finally { PInvokeWrapper.DeleteMiniVan(miniVan); } Marshalling Classes
  • 24. typedef void (CALLBACK *SAYHELLOCALLBACK)(); extern "C" PINVOKE_API void CallMeBackToSayHello( SAYHELLOCALLBACK callback); [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void CallMeBackToSayHello( Action callback); Marshalling Callbacks
  • 25. typedef struct { double a; double b; double c; } TRIANGLE; typedef void (CALLBACK *PYTHAGORASCALLBACK)(TRIANGLE result); extern "C" PINVOKE_API void ReportPythagorasBack( double a, double b, PYTHAGORASCALLBACK callback); [StructLayout(LayoutKind.Sequential)] public struct Triangle { public double a; public double b; public double c; } public delegate void TriangleCallback(Triangle t); [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void ReportPythagorasBack( double a, double b, TriangleCallback callback); Marshalling Callbacks
  • 27. Unsafe C#  Use unsafe keyword Used with type or member Unsafe code block  Adds pointer arithmetic to C# Similar to C#  Unsafe does not mean less safe than normal C# If you use IntPtr, you are not safer In both scenarios, C# does not do any checks for buffer overruns  You can program P/Invoke without unsafe Use IntPtr and methods of the Marshal class instead
  • 28. type *identifier; void *identifier;// Ptr to unknown type int* pNumber; int** ppNumber; int*[] pArray; // Ptr to a ptr to int // Array of int* int* pNumber Console.WriteLine(*pNumber); // Get value that pNumber points to Pointers in C# Supported types sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool. Enums Pointers User-defined structs with unmanaged types
  • 29. namespace FixedSizeBuffers { internal unsafe struct MyBuffer { public fixed char fixedBuffer[128]; } internal unsafe class MyClass { public MyBuffer myBuffer = default(MyBuffer); } internal class Program { static void Main() { MyClass myC = new MyClass(); unsafe { // Pin the buffer to a fixed location in memory. fixed (char* charPtr = myC.myBuffer.fixedBuffer) { *charPtr = 'A'; } } } } } Fixed size buffers Buffer with fixed size Typically used inside a struct Supported data types bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float, or double
  • 31. Tipps & Tricks  BOOL can be marshalled to System.Int32 or bool Marshalling to bool is a little bit slower but convenient See MSDN for details  InAttribute and OutAttribute By default, direction attribute for non-blittable types is In (performance reasons) Best practice: Specify [In, Out] for input and output parameters (even for blittable types) Exception: StringBuilder (In, Out by default) See also sample in MSDN
  • 32. Memory Management  Marshaler always attempts to free memory allocated by unmanaged code Use IntPtr to prevent this  Memory is always freed using CoTaskMemFree Library has to provide a dedicated free method if allocated differently  See MSDN for details about copying/pinning See MSDN for details
  • 33. String Marshalling  System.String for constant strings LPCSTR, LPCWSTR, etc.  System.Text.StringBuilder for string buffers that can change LPSTR, LPWSTR, etc. Always initialize size of the StringBuilder (constructor, Capacity property) StringBuilder are guaranteed to have a terminating null character  Use IntPtr and Marshal.PtrToStringXXX if caller should not free the memory
  • 34. String Marshalling  Use [MarshalAs(UnmanagedType.ByValXXX, SizeConst=XXX)] for fixed size char buffers  See MSDN for details
  • 35. public { // // // static class StringIntPtrHandling Note that GetPrivateProfileSectionNames returns a string with embedded NULL characters. See http://msdn.microsoft.com/en-us/library/windows/desktop/ms724352(v=vs.85).aspx for details. [DllImport("kernel32.dll")] static extern int GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, int nSize, string lpFileName); public static void ExecuteSample() { IntPtr ptr = IntPtr.Zero; string s = string.Empty; try { // Allocate a buffer in unmanaged memory ptr = Marshal.AllocHGlobal(1024); // Call Kernel API var numChars = GetPrivateProfileSectionNames( ptr, 1024, Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Sample.ini")); // Copy the buffer into a managed string s = Marshal.PtrToStringAnsi(ptr, numChars - 1); } finally { // Free the unmanaged buffer if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } } // Display the sections by splitting the string based on NULL characters foreach (var section in s.Split('0')) { Console.WriteLine(section); } } } Strings and IntPtr
  • 36. typedef struct { // Note that this structure contains an array of characters char make[256]; char color[256]; } CARFIXED; extern "C" PINVOKE_API void FillThreeBasicCars(CARFIXED* theCars); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct CarStruct { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Make; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Color; } [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern void FillThreeBasicCars( [In, Out, MarshalAs(UnmanagedType.LPArray)] CarStruct[] theCars); Marshalling Arrays
  • 37. extern "C" PINVOKE_API void GiveMeMakes(BSTR** makes, int *length); [DllImport("PInvokeIntroduction.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public static extern void GiveMeMakes( [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.BStr, SizeParamIndex = 1)] out string[] makes, [Out] out int length); Marshalling Arrays
  • 38. Training Material Rainer Stropek software architects gmbh Q&A Mail rainer@timecockpit.com Web http://www.timecockpit.com Twitter @rstropek Thank your for coming! Saves the day.
  • 39. is the leading time tracking solution for knowledge workers. Graphical time tracking calendar, automatic tracking of your work using signal trackers, high level of extensibility and customizability, full support to work offline, and SaaS deployment model make it the optimal choice especially in the IT consulting business. Try for free and without any risk. You can get your trial account at http://www.timecockpit.com. After the trial period you can use for only 0,20€ per user and day without a minimal subscription time and without a minimal number of users.
  • 40. ist die führende Projektzeiterfassung für Knowledge Worker. Grafischer Zeitbuchungskalender, automatische Tätigkeitsaufzeichnung über Signal Tracker, umfassende Erweiterbarkeit und Anpassbarkeit, volle Offlinefähigkeit und einfachste Verwendung durch SaaS machen es zur Optimalen Lösung auch speziell im IT-Umfeld. Probieren Sie kostenlos und ohne Risiko einfach aus. Einen Testzugang erhalten Sie unter http://www.timecockpit.com. Danach nutzen Sie um nur 0,20€ pro Benutzer und Tag ohne Mindestdauer und ohne Mindestbenutzeranzahl.