13

C で記述された別のプログラムのデータ出力を解析して表示するために、C# で GUI ツールを作成しています。データを解析するには、いくつかの C ヘッダー ファイルで指定されているデータ構造を知る必要があります。したがって、これらの C ヘッダー ファイルを C# プロジェクトに組み込む必要があります。私の質問は次のとおりです。

1) いくつかの調査の後、私のソリューションで新しい C++/CLI プロジェクトを作成し、C ヘッダー ファイルをこの新しいプロジェクトにインポートし、データのシン ラッパーとして機能するいくつかの C++/CLI クラスを記述することが最善の方法であると結論付けました。 C ヘッダー ファイルで定義された構造体を定義し、C# コードから C++/CLI ラッパー クラスを参照します。これが最善のアプローチですか、それとももっと良い方法がありますか?

2) 参照の問題に遭遇しました。問題を説明するための単純化されたコードを次に示します。

C++/CLI プロジェクトの元の C ヘッダー

#define ABC  0x12345

C++/CLI プロジェクトのラッパー クラス

#include "my_c_header.h"

namespace C_Wrappers {
    public ref class MyWrapper {
        public:
            property unsigned int C_ABC {
                unsigned int get() { return ABC; }
            }
    }
 }

C# プロジェクトのユーザー クラス

using C_Wrappers;
using System;

namespace DataViewer {
    public partial class MainForm : Form {
        private  MyWrapper myWrapper = new MyWrapper();
        public MainForm() {
            Console.WriteLine(myWrapper.C_ABC.ToString());
        }
    }
 }

C# プロジェクトでは、C++/CLI プロジェクトへの参照を追加しました (右クリック > [参照の追加] を使用)。ビルド中に C# プロジェクトでエラーが発生しました。

やるべきことはすべてやったと思いました。このエラーを修正するにはどうすればよいですか?

4

2 に答える 2

24

私自身のソリューションでは、4 つのプロジェクトがありました。

  1. C++ プロジェクトとテスト コード
  2. ダイナミック リンクを使用して最初のプロジェクト ソースから DLL をコンパイルするだけのC++ DLL プロジェクト
  3. 生の C++ をラップする、C++/CLI を使用する単なるアダプターであるラッパープロジェクト
  4. 私のグラフィカルインターフェイスであるC #WPFプロジェクト。

上記のリンクの私の翻訳は次のとおりです。

C++ DLL プロジェクト

C++ コードを DLL ライブラリにします。

  1. Visual Studio 内で、File > New > Projectに移動し、Visual C++ タブからWin32 プロジェクトを選択します。
  2. プロジェクトとソリューションの両方の名前を選択します。ソリューションにはすべてのプロジェクトが含まれます。
  3. Win32 アプリケーションのアシスタント内で、[へ] をクリックし、[ DLL ]ボックスをオンにして、[空のプロジェクト] をクリックし、[完了] をクリックします。

プロジェクトの作成 プロジェクトアシスタント

追加するコード

これは、dll の C++ ヘッダーです (多くのものを除く)。

Token.h

#pragma once
#define DLLEXP   __declspec( dllexport )

DLLEXP void pop_back(std::string& str);

DLLEXP std::string testReturnString();

DLLEXP int getRandomNumber();

CPP 内で変更するものは何もありません。

プロジェクトをビルドします。C# プロジェクトのデバッグ ディレクトリに含める DLL と LIB ファイルが必要です。

C++/CLI ラッパー

このプロジェクトは、前のプロジェクトのネイティブ コードと GUI のマネージ コードの間のインターフェイスとして機能します。

  1. 新しいプロジェクト (Visual C++ のクラス ライブラリ) (この例では "Wrapper" と呼ばれます) をソリューションに追加します。
  2. 追加のインクルード ディレクトリを使用して、ネイティブ プロジェクトへのパスを追加します。
  3. 新しいプロジェクトの参照としてネイティブ プロジェクトを追加します (右クリック > [参照...] > [新しいリンクの追加] ) 。
  4. Properties > Linker > Inputで、ネイティブ dll の名前を DLL の遅延ロード (この例では Computations.dll) フィールドに入力します。

C++/CLI コード

私のラッパーは、このようなクラスです(自分のコードを除く)。

Wrapper.h

#include "Token.h" // include your C++ header

#include <string>
#include <iostream>

namespace Wrapper {

    // noticed the ref?
    public ref class TokenAnalyzer
    {

    public:
        TokenAnalyzer(){
        };

        void Init();
            // use the C++/CLI type, like String^ (handles)
        System::String^ ProcessLine(int lineNbr, System::String^ line);
    };
}

を含める必要があることを除いて、CPP 内で特別なことは何もありません#include "stdafx.h"

また、C# デバッグ ディレクトリ内に含める DLL にビルドする必要があります。

SOのどこかで見つけた便利な機能ですが、どこで必要になるか覚えていません。C++/CLI 文字列ハンドルを C++ 標準文字列に変換します。

std::string MarshalString (String ^ s) {
        using namespace Runtime::InteropServices;
        const char* chars = 
            (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
        std::string os = chars;
        Marshal::FreeHGlobal(IntPtr((void*)chars));
        return os;
    }

C# プロジェクト

ソリューションに新しいプロジェクト ( C # Windows フォームまたはWPFまたは任意のもの) を追加し、それをスタートアップ プロジェクトとして設定します (右クリック > スタートアップ プロジェクトとして設定)。

  1. C++/CLI プロジェクトを新しいプロジェクトの参照として追加します
  2. using Wrapper;ソースコード形式でディレクティブを追加

次のように使用します。

/// Store the C++/CLI Wrapper object.</summary>
private Wrapper.TokenAnalyzer mTokenAnalyzer = new TokenAnalyzer();

2016/05/06 更新

Ashwinは、サンプル プロジェクトと、さらに役立つ可能性のあるブログ投稿チュートリアルを作成するために時間を割きました。

于 2013-10-03T16:11:35.017 に答える