【メモ】Native Interops in TinyCLR

TinyCLR OSのInteropをウォークスルーしてみます。

TinyCLR Applicationを新規作成

Visual Studio 2017を起動して、TinyCLR Applicatonプロジェクトを新規作成します。

f:id:matsujirushix:20171126214548p:plain

資料のサンプルコードはフィールド、メソッド、プロパティを宣言していますが、メソッドさえ動けばとりあえずは良いので、メソッドだけ宣言しました。

using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace TinyCLRApplication1
{
    class Program
    {
        static void Main()
        {
            var instance = new MyNativeClass();
            Debug.WriteLine(instance.MyNativeFunc(10, 20).ToString());
        }
    }

    class MyNativeClass
    {
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern int MyNativeFunc(int param1, int param2);
    }
}

Native stubを生成

プロジェクトのプロパティにある、 * Generate native stubs for internal methods * Generate bare native stubs をチェックして、リビルドします。

f:id:matsujirushix:20171126215429p:plain

リビルドした後は、元に戻しておきます。(両方ともチェックを外す)

リビルドした結果、bin/Debug/pe/Interop配下に、 * TinyCLRApplication1.h * TinyCLRApplication1.cpp * TinyCLRApplication1_TinyCLRApplication1_MyNativeClass.cpp が生成されます。

f:id:matsujirushix:20171126220000p:plain

中身は次のとおり。

TinyCLRApplication1.h

#pragma once

#include <TinyCLR.h>

struct Interop_TinyCLRApplication1_TinyCLRApplication1_MyNativeClass {
    static TinyCLR_Result MyNativeFunc___I4__I4__I4(const TinyCLR_Interop_MethodData md);
};

extern const TinyCLR_Interop_Assembly Interop_TinyCLRApplication1;

TinyCLRApplication1.cpp

#include "TinyCLRApplication1.h"

static const TinyCLR_Interop_MethodHandler methods[] = {
    Interop_TinyCLRApplication1_TinyCLRApplication1_MyNativeClass::MyNativeFunc___I4__I4__I4,
    nullptr,
    nullptr,
    nullptr,
};

const TinyCLR_Interop_Assembly Interop_TinyCLRApplication1 = {
    "TinyCLRApplication1",
    0xAA047403,
    methods
};

TinyCLRApplication1_TinyCLRApplication1_MyNativeClass.cpp

#include "TinyCLRApplication1.h"

TinyCLR_Result Interop_TinyCLRApplication1_TinyCLRApplication1_MyNativeClass::MyNativeFunc___I4__I4__I4(const TinyCLR_Interop_MethodData md) {


    return TinyCLR_Result::NotImplemented;
}

Interop_TinyCLRApplication1 -> methods -> Interop_TinyCLRApplication1_TinyCLRApplication1_MyNativeClass::MyNativeFuncI4I4I4 と参照しているので、メソッドの実装はTinyCLRApplication1_TinyCLRApplication1_MyNativeClass.cppのInterop_TinyCLRApplication1_TinyCLRApplication1_MyNativeClass::MyNativeFuncI4I4I4 に書けば良いようです。

methods の配列が4なのが気になります。なにか意味があるのだろうか?

さらに、メソッドの引数の型、TinyCLR_Interop_MethodData も謎。

(つづく)