2017-11-10 9 views
2

私は、C++で複雑な文字列を解析し、そこからツリーを作成するコードを書いています。 Visual Studio 2017でC#を使用して、ノードのベクトルを返すネイティブなC++メソッドを呼びたいと思います。構造をCに渡す

Aノードは、次のようになります。

class node 
{ 
    public: 
    std::vector<node> subnodes; 
    std::string name; 
}; 

とC++関数は次のようになります。noderizer::getNodes(...)を呼び出す(スピードのための二次的考慮して時間をコーディング)は、最も効率的な方法は何か

class noderizer 
{ 
public: 
    node getNodes(std::string str); 
}; 

メンバーと同等のクラスを作成するC#?

私は最善のルートがC#で重複したクラス定義を作成することであると仮定して、this articleは、Cの最新情報が含まれている場合、それははっきりしていない管理Strings

public class node 
{ 
    public string name = string.Empty; 
    List<node> integers = new List<node>(); 
} 

にネイティブstd::stringsをマーシャリングコピー++相互運用していますしかし、C#で使用するwrapping c++ native classesに関する関連記事は、noderizerネイティブC++をnoderizer * m_Impl;とし、getNodesのメンバーに電話し、各パラメータをコピーすることが最も可能性が高いことを示しています。

+0

はい、マネージC++を使用したり、COMを介してC++メソッドを公開したりすることができます。 – wp78de

+1

C#で*と*のツリー構造を同じにする利点は何ですか?それは本当にこのすべての使用法が何であるかにかかっています。通常は(特に、管理されているものと管理されていないものの両方を所有している場合)、使用法/シナリオに言語を捧げるので、両方の言語ですべてを行う/コードする必要はありません。 –

+0

@ wp78de明示的なメリットがないことはわかりませんが、C++のデータ構造をどのように拡張するのか分かりません。私の理解は、管理されたコードとアンマネージコードの間で文字列ベクトルを手動で転送する必要があるということです。 – Steve

答えて

2

最初の参照記事でpInvokeを使うことができますが、返すオブジェクトはかなり複雑に見えます。私はあなたがまだよく熟知していない(そしてそれでも)場合、マーシャリングのデータで時間の問題があると思います。 pInvokeは、データ・マーシャリングが基本的なCライブラリへの単純な呼び出しには最適ですが、非常に複雑になります。これはあなたの状況には適していません。

第二の記事は、あなたが見てみたい場所に近いです。つまり、マネージクラスをラップするか、文字列を受け取り、管理された形式でツリーを返す(つまり、アンマネージデータをラップするのではなくコピーを作成する)関数を呼び出すかどうかを検討する必要があります。あなたの投稿では、後者が必要なようです。

あなたの最良のオプションは、C++/CLIを使用することです。 this tutorialをチェックしてください。私はこのアプローチを取ることがあなたの仕事の軽い仕事をすると確信しています。私は上記の記事が非常に良い仕事をしているので、主題を説明しようとはしません。本質的に、すべてのデータ・マーシャリングが環境に組み込まれている、管理されたデータ型と管理されていないデータ型の両方で書込み機能を使用できるようになります。シンプルなキャストは、あなたのためにデータをマーシャルします。大きな利点として、デバッグは、C#からC++/CLIからC++のコードに戻って戻ることができるのですばらしいです。

上記の記事では、作成者はアンマネージドクラスをラップする方法について説明していますが、それでも問題はデータ変換にあります。

私は4つのステップであなたの問題にアプローチします:

  1. は、あなたが引数としてstringを渡し、任意の通常の静的メソッドとしてのC#から呼び出すことができますC++/CLIでの静的関数getNodes()を書きます。上記の記事はあなたに役立ちます。また、C++/CLIプロジェクトの作成時にSee Here
  2. getNodes()は、C++コードを使用してtreeをアンマネージ形式で作成します。
  3. treeをアンマネージド形式から管理形式に変換する場合は、getNodes()を使用してください。
  4. 結果をC#の呼び出し元に返します。

あなたの宣言がNodeは、管理対象calssは、refキーワードは、クラスが管理されていることを意味しており、^*の管理バージョンであり、このようなものを、見ていきます。

public ref class noderizer 
{ 
public: 
    static Node^ getNodes(String ^mStr); 
}; 

ここでgetNodes()は、C++関数を呼び出してデータ変換を行います。私はそれを理解するのにあなたが長くかかるとは思わない。 構文のハングを取得したら、C#とC++に精通していれば、直感的に使用することができます。

パフォーマンスに関しては、何千もの連続した通話を行っているか、重要なリアルタイムデータが必要な場合を除き、問題ではありません。あなたがパフォーマンスに関心があるなら、純粋なC++コードを純粋に管理されていない別のdllに書くべきです。私は私の人生のための記事を見つけることができませんが、純粋に独自の内部でコンパイルされた全く同じコードを呼び出す対C + +/CLIのDLL内でコンパイルされた純粋に管理されていない長い実行コードブロックを実行するいくつかのベンチマークを見て覚えているアンマネージドDLL。私が正しくリコールすれば、別のDLLは3倍速いものでした。

関連する問題