Cで記述された別のプログラムのデータ出力を解析して表示するGUIツールをC#で記述しています。データを解析するには、いくつかの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#プロジェクトでエラーが発生しました:「タイプまたは名前空間 'C_Wrappers'が見つかりませんでした(usingディレクティブまたはアセンブリ参照がありませんか?)」
やるべきことはすべてやったと思った。このエラーを修正するにはどうすればよいですか?
私自身のソリューションでは、4つのプロジェクトがありました。
これが上記のリンクの私の翻訳です。
C++コードをDLL libに作成します。
これは、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ファイルが必要です。
このプロジェクトは、前のプロジェクトのネイティブコードとGUIのマネージコード間のインターフェイスとして機能します。
私のラッパーは、このようなクラスにすぎません(私自身のコードを除く)。
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);
};
}
#include "stdafx.h"
を含める必要があることを除いて、CPP内で特別なことは何もありません。
また、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#Windowsフォームまたは[〜#〜] wpf [〜#〜 ]またはあなたが望むものなら何でも!)そしてそれをスタートアッププロジェクトとして設定します(右クリック>スタートアッププロジェクトとして設定します )。
using Wrapper;
を追加します次のように使用します。
/// Store the C++/CLI Wrapper object.</summary>
private Wrapper.TokenAnalyzer mTokenAnalyzer = new TokenAnalyzer();
更新2016/05/06
Ashwin 時間をかけて サンプルプロジェクト と ブログ投稿チュートリアル を作成しました。これはさらに役立つ可能性があります。
私にとって、 this 同様の質問に対する答えは、C#での同じエラーを解決しました。
(つまり、C++\CLIプロジェクトにラッパーヘッダーファイルがありましたが、.cppファイルも含めるのを忘れていました(#include "stdafx.h"と#include "Wrapper.hの2行しかないにもかかわらず) "))