none
C++/CLIについて RRS feed

  • 質問

  • お世話になります。

    C++/CLIの勉強を始めようとしているもので、いろいろと参考となるページを読んでいるのですが、
    なぜアンマネージコードとマネージコードが混在できるのか、またコンパイルされたアセンブリは、
    ネイティブ・マネージの混在アセンブリなのかなどの説明がのっているものがなく、そのような書籍・ページがあれば
    教えてください。

    int main()
    {
     printf("HELLO");
      System::Console::Write(L"HELLO");
    }

    このような使い方ができるとはいろんなページに記述されているのですが、コンパイルとするとprintfはマシン語で出力され
    Console::Writeは、MSIL語に出力されて・・・よびだされたとき・・・XXXX(勝手なイメージですが)などの説明がされているものがあれば
    ありがたいのですが・・・。

     

     

    2010年11月9日 6:16

回答

  • 実装詳細ということであれば http://vene.wankuma.com/ecma372/StartingState.aspx が参考になると思います。

    ISOではありませんが、一応は標準化され詳細が公開されています。これじゃ納得できないのなら原文あたってください。というくらいかな?

    逆に細かすぎてなんだかわからないのなら、http://msdn.microsoft.com/ja-jp/library/68td296t.aspx この辺から読んでみるのが良いかと。

    訳のほうは .NET 2のころのものなのでちょっと古い部分もあります。とはいえ、大きく仕様が変わったというわけでもないので学ぶ上で影響するものは少ないと思います。

     


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/
    • 回答としてマーク OTAKA 2010年11月10日 2:42
    2010年11月9日 7:54
  • Compileした実行ファイルをILDasmで見てみましょう。

    printfの呼び出しは以下のようになります。

    IL_0007:  call       vararg int32 modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) printf(int8 modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)*)

     

    printf自体は以下のようになります。

    .method assembly static pinvokeimpl( lasterr cdecl)
            vararg int32 modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)
            printf(int8 modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)* A_0) native unmanaged preservesig
    {
      .custom instance void [mscorlib]System.Security.SuppressUnmanagedCodeSecurityAttribute::.ctor() = ( 01 00 00 00 )
      // Embedded native code
      // Disassembly of native methods is not supported.
      //  Managed TargetRVA = 0x00002BE6
    } // end of method 'Global Functions'::printf

    System::Console::Writeは以下のようになります。

      IL_0012:  call       void [mscorlib]System.Console::Write(string)

     

    >そのような書籍・ページ

    私から紹介できませんが、上記の情報などから検索してみるとよいでしょう。

    • 回答としてマーク OTAKA 2010年11月10日 2:42
    2010年11月9日 8:12

すべての返信

  • 「関数」について深いレベルで理解されていますでしょうか?

    挙げられているprintf()はMSVCR100.DLLに、System::Console::Write()はmscorlib.dllに、それぞれ格納されており、main()関数はそれらを呼び出しているにすぎません。またアンマネージコード⇔マネージコード間の行き来は自由です。

    なので、想像されているような、1つの関数内にアンマネージコードとマネージコードが混在している関数が作られているわけではありません。

    …ということもあり、説明するほどのものではないのかもしれません。

    2010年11月9日 7:00
  • 実装詳細ということであれば http://vene.wankuma.com/ecma372/StartingState.aspx が参考になると思います。

    ISOではありませんが、一応は標準化され詳細が公開されています。これじゃ納得できないのなら原文あたってください。というくらいかな?

    逆に細かすぎてなんだかわからないのなら、http://msdn.microsoft.com/ja-jp/library/68td296t.aspx この辺から読んでみるのが良いかと。

    訳のほうは .NET 2のころのものなのでちょっと古い部分もあります。とはいえ、大きく仕様が変わったというわけでもないので学ぶ上で影響するものは少ないと思います。

     


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/
    • 回答としてマーク OTAKA 2010年11月10日 2:42
    2010年11月9日 7:54
  • Compileした実行ファイルをILDasmで見てみましょう。

    printfの呼び出しは以下のようになります。

    IL_0007:  call       vararg int32 modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) printf(int8 modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)*)

     

    printf自体は以下のようになります。

    .method assembly static pinvokeimpl( lasterr cdecl)
            vararg int32 modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)
            printf(int8 modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)* A_0) native unmanaged preservesig
    {
      .custom instance void [mscorlib]System.Security.SuppressUnmanagedCodeSecurityAttribute::.ctor() = ( 01 00 00 00 )
      // Embedded native code
      // Disassembly of native methods is not supported.
      //  Managed TargetRVA = 0x00002BE6
    } // end of method 'Global Functions'::printf

    System::Console::Writeは以下のようになります。

      IL_0012:  call       void [mscorlib]System.Console::Write(string)

     

    >そのような書籍・ページ

    私から紹介できませんが、上記の情報などから検索してみるとよいでしょう。

    • 回答としてマーク OTAKA 2010年11月10日 2:42
    2010年11月9日 8:12
  • 皆様ご返事ありがとうございます。

    KOZZさんの手法でアセンブリを参照することでどのようになっているのかなんとなく理解ができます。
    ILDASMで出来上がったものを参照すればよかったのですね。

    参照できるということは、CLRヘッダーをもつアセンブリでCLR上で動作するアセンブリで
    アンマネージコードの関数は、P/INVOKEでラップされた関数が生成されそのなかで呼ばれることになるのですね。

    とっちゃんさんから頂いた、http://msdn.microsoft.com/ja-jp/library/68td296t.aspx から
    「混在 (ネイティブおよびマネージ) アセンブリ」の章をみつけたので、混在アセンブリを勉強したいと思います。

    ありがとうございました。

    2010年11月10日 2:42