.net, .net core, Powershell, Raspberry Pi 3

Using PInvoke with .NET Core 2 and Windows 10 IoT Core on the Raspberry Pi 3

Since I’ve been kicking the tyres on .NET Core 2 to see what’s possible with the Raspberry Pi 3, I wondered if it was possible to use PInvoke on the Windows 10 IoT Core operating system – and it turns out that it is.

Let’s write a simple console application and deploy it to a Pi 3 to show PInvoke working.

As usual, you can find the finished code on my GitHub repository here.

First, install .NET Core 2

You can get the .NET Core 2 installer from here – remember that this version of .NET Core hasn’t made it to RTM status yet, so you’re playing with code at the bleeding edge. I’ve found it to be pretty stable, but I’m working on a machine which I’m happy to trash and rebuild.

screenshot.1492889096

Create a console app for the Raspberry Pi 3

Next, open a PowerShell prompt, and navigate to where you want to create the .NET Core 2 project.

dotnet new -i RaspberryPi.Template::*

This’ll add the template for a .NET Core 2 Console application which targets IoT devices – you can see this in your list of installed templates if you run:

dotnet new --list

You’ll see it in the list, as shown below.

screenshot.1493574830

So to create this kind of IoT console application, run:

dotnet new coreiot -n RaspberryPi.PInvoke

This creates a new folder and project called “RaspberryPi.PInvoke”, which presently will just write “Hello Internet of Things!” to the console.

Choose an unmanaged function to call – CharUpper

Let’s change this application to make that text – “Hello Internet of Things!” – become upper case. Inside user32.dll, there is a function called CharUpper which will do exactly that.

Obviously we could just use the “ToUpper()” string method inside managed .NET code to achieve this, but this application is a proof of concept to use PInvoke.

The C# signature for this is below:

[DllImport("user32.dll", CharSet=CharSet.Auto)]
static extern char CharUpper(char character);

So we can modify our very simple program to now become like the code below:

using System;
using System.Runtime.InteropServices;
 
namespace RaspberryPiCore
{
    class Program
    {
        [DllImport("user32.dll", CharSet=CharSet.Auto)]
        static extern char CharUpper(char character);
 
        static void Main(string[] args)
        {
            var textToChange = "Hello Internet of Things!";
            var inputCharacterArray = textToChange.ToCharArray();
 
            // array of chars to hold the capitalised text
            var outputCharacterArray = new char[inputCharacterArray.Length];
 
            for(int i = 0; i < inputCharacterArray.Length; i++) 
            {
                outputCharacterArray[i] = CharUpper(inputCharacterArray[i]);
            }
 
            Console.WriteLine($"Original text is {textToChange}");
            Console.WriteLine($"Changed text is {new string(outputCharacterArray)}");
        }
    }
}

Let’s build this using:

dotnet build

Let’s publish it for Windows 10 IoT Core devices with an ARM processor using

dotnet publish -r win8-arm

Let’s open a Powershell prompt to our Raspberry Pi 3, create a folder to host this application.

mkdir c:\ConsoleApps\PInvoke

You can ssh to your Raspberry Pi 3 using a Powershell prompt from the Windows IoT Dashboard as shown in the image below:

screenshot.1489958874

And now let’s open a command prompt on our development machine, and copy the application binaries to the directory we created on our Raspberry Pi 3 earlier.

robocopy.exe /MIR ".\bin\Debug\netcoreapp2.0\win8-arm\publish" "\\<your-ipaddress-here>\c$\ConsoleApps\PInvoke"

Finally after building, publishing and deploying, we can go back to the ssh PowerShell prompt and run:

C:\ConsoleApps\PInvoke\RaspberryPi.PInvoke.exe

And this shows the text has been changed to upper case, as shown below.

screenshot.1493578558

Wrapping up

There’s nothing special about this code, it’s all pretty standard PInvoke code – but it’s nice to confirm that it works with .NET Core 2 on the Raspberry Pi 3’s ARM processor under Windows 10 IoT Core.