[コープ短文]C#でC言語関数を呼び出す(静的呼び出しNative DLL,Windows&Microsoft.Netプラットフォーム)


本文は「科学普及」の性質に属し、対に向いている.Netの知らない読者.
 
よくわかりません.Netの人は、知りたいなら.Net、P/Invokeを紹介しなければなりません.P/Invokeって何ですか?簡単に言えば、そうです.Netでローカルコード(Native code)を呼び出すソリューション.「ローカルコード」とは、管理コード(Managed code)に対するものである.
P/Invokeは実に素晴らしい特性です.本来、.Netという技術は、管理プログラム(Managed program)の様々なメリットを十分に証明しているが、「最下位」ではない.しかし、これは何の関係があるのだろうか.P/Invokeがあります!これにより,管理コードの利点とローカルAPIを呼び出す必要性がシームレスに融合する.
「C#を覚えたばかりで、とても素敵で便利だと思います.私の質問は、メール猫(SMS Modem)メーカーが提供するインタフェースAPIを呼び出すことができますか?これらのインタフェースAPIはC++ですね~」......OK、今P/Invokeを知ったら、この方面の懸念を完全に解消することができます.
 
雑談はさておき,われわれの例を見てみよう.
私たちの例は、C言語で書かれた関数を動的リンクライブラリにカプセル化し、C#プログラムで簡単に呼び出すことです.
このような例を実現することは多くの人にとって本当に意義が大きく、これから心配しなくてもいい.Netは「最下位」ではありません.
 
まず、C言語関数を見てみましょう.
 
int sum(int a, int b)
{
	return a + b;
}

簡単でしょう.
 
 
一、動的リンクライブラリに関数インタフェースを露出する
 
ダイナミックリンクライブラリにカプセル化することにしました.ダイナミックリンクライブラリにカプセル化できるように、この関数の説明の前にこれを追加します.
 
__declspec(dllexport)

ソースコードは次のようになります.
 
 
__declspec(dllexport) int sum(int a, int b)
{
	return a + b;
}

 
 
 
二、コンパイル、ダイナミックリンクライブラリを得る
 
次に、Visual C++に付属のコマンドラインツールcl、linkを使用してダイナミックリンクライブラリにカプセル化します.ファイル名をTestとする.c、私たちはTestを望んでいます.dll、コマンドは次のとおりです.
 
cl /c Test.c  
link /dll Test.obj

gccでコンパイルしてTestを得ることもできます.dll.コマンドは次のとおりです.
 
 
gcc -shared -o Test.dll Test.c

今すぐ手に入れたdll.
 
 
注:Test.cはTestを得る.dllの方法はたくさんありますが、詳しく知りたいなら2つの小文を読んでください.
  • C言語ソースコードを動的リンクライブラリにコンパイルするhttp://blog.csdn.net/xinyaping/article/details/7284899
  • Visual C++2010 Express Tips:CとC++でダイナミックリンクライブラリを作成するhttp://blog.csdn.net/xinyaping/article/details/7288164

  •  
    三、C#でP/InvokeでTestを呼び出す.dllでのsum()メソッド
     
    P/Invokeは簡単です.次の簡単なC#コードを見てください.
     
    // -----------------------------------------------------------------------
    // 
    // P/Invoke example.
    // 
    // -----------------------------------------------------------------------
    
    namespace Invoke
    {
        using System;
        using System.Runtime.InteropServices;
    
        /// 
        /// .Net P/Invoke example.
        /// 
        internal class Program
        {
            /// 
            /// Entry point of the application.
            /// 
            /// Console arguments.
            internal static void Main(string[] args)
            {
                int result = Sum(2, 3);
                Console.WriteLine("DLL func execute result: {0}", result);
            }
    
            /// 
            /// Call method int sum(int, int) defined in Test.dll
            /// 
            /// parameter a
            /// parameter b
            /// sum of a and b
            [DllImport("Test.dll", EntryPoint = "sum")]
            private static extern int Sum(int a, int b);
        }
    }
    

    上のコードは簡単でしょう.注釈を除いて、コンソール出力を除いて、七零八砕の部分を除いて、残りのものはこれです.
     
     
     
     
            [DllImport("Test.dll", EntryPoint = "sum")]
            private static extern int Sum(int a, int b);

    これが有名なP/Invokeです.ここでわざとC言語のソースコードとは異なる関数名Sumを使ったことに注意してください.C言語のソースコードの関数名はsumです.C#もsumという関数名を使うと、DLImportはこのように書くことができます.
     
     
    [DllImport("Test.dll")]

     
     
     
    ここでは、C#の関数名とDLLの関数名が一致しない場合にEntryPointでマッピングできることを示します.
     
    このC#プログラムをコンパイルして実行して、実行する時Testを忘れないでください.dllは実行ディレクトリにコピーされます.結果はもちろん予想されています.
     
    例は簡単で、意味は簡単ではありません.
     
    参考文献:
  • C言語ソースコードを動的リンクライブラリにコンパイルするhttp://blog.csdn.net/xinyaping/article/details/7284899
  • Visual C++2010 Express Tips:CとC++でダイナミックリンクライブラリを作成するhttp://blog.csdn.net/xinyaping/article/details/7288164
  • An Introduction to P/Invoke and Marshaling on the Microsoft .NET Compact Frameworkhttp://msdn.microsoft.com/en-us/library/aa446536.aspx
  • Essential P/Invoke http://www.codeproject.com/Articles/12121/Essential-P-Invoke
  • .Netは何ができるのかhttp://blog.csdn.net/xinyaping/article/details/6722015

  •