web-dev-qa-db-ja.com

C#でC ++ APIを使用する方法はありますか?

ヘッドトラッキングデータを取り込み、それに応じて3Dオブジェクトを画面上で移動する小さなプログラムをコーディングします。これを達成するために、C++ APIを備えたopentrackというソフトウェアを見つけました。問題は、私が知っている、またはC#を言語として使用してアクセスできるゲーム開発環境があることです。

私はC#に非常に慣れており、以前はC++とCに慣れていたため、ソリューションで必要な場合は簡単に元に戻すことができました。

これはばかげた小さな個人的なプロジェクトですが、私は情熱を持っており、解決したいので、これを解決するための助けがあれば感謝します。ありがとう!

更新:

うわー、それは驚くほどの量と質の高い応答です。貢献してくれたすべての人に深く感謝します!

30
zoliking

C#からネイティブコードを呼び出す方法はいくつかあります

  1. P/Invoke -c#コードから直接cスタイルのメソッド呼び出しを許可します。 APIがcスタイル(extern Cなど)の関数を公開しない場合は、これを行うラッパーが必要になります。 APIが任意の種類のオブジェクトを使用する場合、これはおそらく苦痛なアプローチになります。
  2. C++/CLI -これにより、c ++プロジェクトで.Netタイプを使用できます。したがって、opentrack APIとインターフェースし、通常のc#コードから呼び出されるラッパーc ++プロジェクトを作成します。 これは、これを行う方法についての素晴らしいガイドのように見えます。 。この利点は、オブジェクト指向のAPIを提供するためにオブジェクトのラッパーを作成できることです。
44
JonasH

オブジェクト指向APIの場合、.NETラッパーを自動的に生成するツールの使用を検討する必要があります。 GitHubで CppSharp を確認してください。すべてが自動的に機能するわけではありませんが、100個のクラスをラップする場合は、相互運用に必要なコードの大部分を生成するのが理にかなっています。

いくつかのクラスをラップするだけでも、SDK全体でも、独自のC++/CLI相互運用性コードを作成する場合でも、アンマネージコードとアンマネージコードを扱うため、C++/CLIコードを別のアセンブリに含めることは常に良い習慣です。単一のコンポーネントに集中させたいデバッグ。

12
helb

確かにできます。私は.NET Core 3.1を使用してWindowsとMacの両方でそうしましたが、ほとんどの場合、最小限の変更で.NET Frameworkでも動作します。

私が使用した方法はDllImportと呼ばれ、ここで説明されています: https://docs.Microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute?view=netframework -4.8#例

以下は、私自身のC#コードの例です。

    class Program
    {
        // This is where you declare the functions from the C file that you want to use. The filename is a relative path to the file containing the `Program`
        [DllImport("libHello.dll")]
        static extern string say_hello(byte[] buffer);

        static void Main()
        {
             var buffer = new byte[1024]; // create byte buffer
             say_hello(buffer) // call the C function
             Console.WriteLine(Encoding.ASCII.GetString(buffer)) // 'hello'
        }

最も重要な部分は、使用しているCライブラリが、実行しているプラ​​ットフォーム用にコンパイルされていることを確認することです。

大きなデータをC#プログラムに返す場合は、cJSONというライブラリを使用し、C構造体をJSONとしてbufferに渡して、逆シリアル化することを検討できます。 C#クラスのインスタンスに。これが私が行った方法であり、C#コードからヒープ領域を解放することについて心配する必要がないので、Cの複雑さを実際に抑えています。

C開発にMicrosoft以外のツールを使用して上記を達成したことに注意してください(もちろん、C#には.NET CoreとCLIを使用しました)。私は特にVisual StudioとVisual C++が好きではありません。それは私自身のバイアスです。

4

SWIG-Simplified Wrapper and Generator は、このようなことを行うための唯一の健全な方法です。 @helbによって言及された CppSharp がその上に構築されているようです。したがって、CppSharpを使用してください。ホイールを再発明する必要はありません。

SWIGは、完全を期すためだけでなく、場合によっては単純な場合もあることを指摘しています。 CppSharpの経験はありません。

C++/CLI については、それを使用して新しいプロジェクトを開始することはありません。 「Hello World」プロジェクトすらありません!これは、WCF、WPF、WinForms、ODataなどのMicrosoftテクノロジで生涯を浪費した人物と言っています。私は間違っているかもしれませんが、私はそれに石を賭けません。はい、私は this を読みましたが、それが.Netの最終ラップアップになるとはまだ確信していません。

0