C#でプリプロセッサ

コメントへのレスです。(^^; Nemerleのマクロだとコンパイル時と実行時の両方で呼び出されるので、コンパイル時にごにょごにょすれば出来そうですが、C#ではそんな小細工出来ないので、コメントとか#if〜#endifとかで埋め込んで処理するしか無い気がしますね。例えばこんな感じ?

using System;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using __int64 = System.Int64;

class Class1 {
#if inline_cpp
    LARGE_INTEGER tsc;

    __asm{
      rdtsc
      mov tsc.LowPart, eax
      mov tsc.HighPart, edx
    }

    __asm {
      rdtsc
      sub eax, tsc.LowPart
      sbb edx, tsc.HighPart 
      mov tsc.LowPart, eax
      mov tsc.HighPart, edx        
    }
    return tsc.QuadPart;
#else
  [System.Security.SuppressUnmanagedCodeSecurity]
  [DllImport("RDTSC.DLL")]
  public static extern __int64 RDTSC();
#endif

  [STAThread]
  static void Main(string[] args) {
    int lvl = 0;
    string line;
    string filename = @"..\..\Class1.cs";
    ArrayList code = new ArrayList();

    using (StreamReader sr = new StreamReader(File.OpenRead(filename))) {
      while ( (line = sr.ReadLine()) != null) {
        if (Regex.IsMatch(line, @"^[\s]*#if[\s]+inline_cpp")) {
          lvl = 2;
        }
        else if (lvl == 1 && Regex.IsMatch(line, @"^[\s]*#endif")) {
          lvl = 0;
          // 関数の書き出し
          // 書き出し先ファイルはDllImportのDLL名に.cppつければ良いかな?
          // ヘッダファイルの指定方法はどーしたらいいかしら・・・
          Console.WriteLine("{");
          foreach (string s in code)
            Console.WriteLine(s);
          Console.WriteLine("}");
          code.Clear();
        }
        else if (lvl == 2 && Regex.IsMatch(line, @"^[\s]*#else")) {
          lvl = 1;
        }
        else if (lvl == 1) {
          // 関数名取得
          Match m = Regex.Match(line, @"^[\s]*public[\s]+static[\s]+extern[\s]+([^;]+);");
          if (m.Success) {
            Console.WriteLine(m.Groups[1]);
          }
        }
        else {
          if (Regex.IsMatch(line, @"^[\s]*#if"))
            lvl++;
          else if (Regex.IsMatch(line, @"^[\s]*#endif"))
            lvl--;
          if (lvl >= 2)
            code.Add(line);
        }
      }
    }
  }
}

/* 結果
__int64 RDTSC()
{
                LARGE_INTEGER tsc;

                __asm{
                        rdtsc
                        mov tsc.LowPart, eax
                        mov tsc.HighPart, edx
                }

                __asm {
                        rdtsc
                        sub eax, tsc.LowPart
                        sbb edx, tsc.HighPart
                        mov tsc.LowPart, eax
                        mov tsc.HighPart, edx
                }
                return tsc.QuadPart;
}*/

ヘッダファイルをどうするのかとか関数の引数はどーなるのかとか__int64が苦肉の策だとか問題がいっぱい。(^^;

あと、例で使っているインラインアセンブラこちらのCによる時間計測を参考にさせていただきました。