Wankuma.Interop.InteropQueryPerformanceCounter Version1

わんくまライブラリ Wankuma.Interop.InteropQueryPerformanceCounter Version1より
えーっと、ダウンロードしてないです、ソースは Web からみれるものを1枚見ただけ
P/Ivoke の戻り値が short になっていますが API の定義は Windows Types BOOL 型なので、対応する .NET 型は UnmanagedType.Bool へマッピングされなければなりません。これは標準では System.Int32 になっています。この場合は MarshalAsAttribute を利用して

private static extern [MarshalAs(UnmanagedType.Bool)]bool ....

と、戻値のマーシャリング型を指定することで .NET 側から透過的に真偽判定を行うことができます。個人的には、P/Invoke の定義は開発ガイドに従って

public class PerformanceCounter
{
  // マネージドインターフェスとしての QueryPerfomanceCounter の定義
  public long PerformanceCounter
  {
    get
    {
      long value;
      if (NativeMethods.QueryPerformanceCounter(ref value) != 0)
      {
        return value;
      }

      // GenerateWin32Exception("QueryPerfomanceCounter", Marshal.GetLastWin32Error());
      throw new NotSupportException();
    }
  }

  // ネイティブインターフェスの定義は NativeMethods というインナークラスに配置する
  private class NativeMethods
  {
    // マネージドインターフェスを別途定義する前提で、API 定義は Win32 に
    // 対して素直な形で定義する。例えば
    /// <return>If the function succeeds, the return value is nonzero.</return>
    // という定義なので、nonzero を判定できる int で定義する。
    public static extern int QueryPerformanceCounter(ref long counter);
  }
}

と、NativeMethods クラスを経由するべきかもしれません。さらに QueryPerformanceCounter という API の要求から、現状の Web に掲載されているコードではオーバーヘッドが高すぎて分解度と計測誤差が大きく差がでてしまっています。

  [SuppressUnmanagedCodeSecurity]
  private class NativeMethods

と、セキュリティチェックをすっとばし、*1blittable 型のデータマーシャリングにおけるスタック上の変換を無効化し、

  [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]

    or/and

  new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

のように、別経路でのセキュリティチェックを施すことで、API の性能をある程度引き出すことができるようになるでしょう。*2 *3

何も見ないで書いているため、コンパイルできないコードを提示している可能性がありますが、何が必要なのかはわかるだろうから気にしないことにします(苦笑

*1:本来はクラスではなくメソッドに付与するのがベターでしょう

*2:手軽かつ狭範囲にしか意味がなくて危険な位置はクラスコンストラクタでセキュリティチェックを行うこと

*3:わんくまの場合はインスタンスを生成しているので、インスタンスの生成に対してセキュリティをチェックして、別コンテキストに対して使いまわすことを暗黙的に禁止する程度がベターなのではないかと思ったり