2016-05-23 4 views
0

C#ライブラリ(VC++ 6.0)で書かれた外部プログラムからいくつかのメソッドを使用できるようにする必要があります。私はこのように、今までかなり正常に動作する混合アセンブリを作成しましたが、.NETオブジェクトの配列を返すメソッドにはいくつかの問題があります。オブジェクトのC#配列をC++/CLIに渡す

方法の.NETシグネチャは次のとおりです。

Results自体はある
public Results[] Measure(String model, String identifier); 

public class Results 
{ 
    public String[] ElementType; 
    public bool[] HasError; 
} 

C++からのエントリポイントを提供するために、私はC++/CLIを書き始めましたこのようなラッパーメソッド:

std::vector<ResultsWrapper> Measure(char* model, char* identifier) 
{ 
    // Call .NET code 
    String^ gcmodel = gcnew System::String(model); 
    String^ gcidentifier = gcnew System::String(identifier); 
    cli::array<Results^>^ gcres = myNetInstance->Measure(gcmodel, gcidentifier); 

    // Convert results to C++ vector 
    std::vector<ResultsWrapper> ret; 
    for (int ki = 0; ki < res->Length; ki++) 
    { 
     ResultsWrapper r = ResultsWrapper(res[ki]->....,); 
     ret.push_back(r); 
    } 

    return ret; 
} 

しかし、私は少し失われていることを認めなければならない、これはC++の単一行を書いていない、非常に長い時間です。私はと手をつないでいません。メモリ管理...

ResultsWrapperクラスを作成する最良の解決策は何ですか。そのため、C++側からのメモリ管理を気にする必要はほとんどありません。次のようなものでしょうか?

class ResultsWrapper 
{ 
    public: 
     ResultsWrapper(vector<std::String> elementType, vector<bool> hasError) 
     { 
     this.ElementType = elementType; 
     this.HasError = hasError; 
     } 

    public: 
    vector<std:String> ElementType; 
    vector<bool> HasError; 
} 

NB:私はVC++ 6.0側のチームは、ブーストライブラリまたはshare_ptrの種類を認識しているとは思わない(と私はどちらかそれらについて非常に知識豊富ではありませんよ)。すべてのC++コードは非常に古典的なC++コードスタイルであり、stdlibを使用していません。 C++/CLIで

+0

私は配列を最初に直列化し、次にdeserializeする必要があると思います – pedrofernandes

+0

@ pho3nixあなたは正しいです。少なくとも、あなたがC++/CLIの賞金をすべて無視して、その言語が提供するものを知らないのであれば。それ以外の場合、あなたは完全に不必要なことをしています。素晴らしいプログラミング。 – TomTom

+2

std :: vectorは使用できません。コンパイラは古すぎます。同様の理由でメモリ管理も問題であるため、* new *で配列を割り当てることもできません。 LocalAlloc()またはSafeArrayCreate()を使用してどこかに移動します。 –

答えて

0

私だけ...その後しばらくの間...ので、私は戻って古いchar**に取得、および手動割り当て/割り当て解除とそれだけで働いたDLLの境界を越えて安全に

IJWを/簡単にSTL型を渡すことができませんでしたI .NETから例外をスローして呼び出し元のC++アプリケーションに戻した後、patatra ...ネイティブ例外に変換する必要があるかどうかをチェックしようとしましたが、これもやはりdll境界を安全に越えることはできません...

混合モードアセンブリは、.NETからネイティブに移行するのは魅力的でしたが、私の場合はIJSの経験でした...私はあきらめて、代わりにCOMを経由します。

0

私はこのようなラッパーメソッドを記述するために開始しました:

いいえ、あなたは

公衆結果[]測定(文字列モデル、文字列の識別子)しませんでした。

のstd ::ベクトル測度(チャー*モデルのchar *識別子)

なしには類似性を有していません。

C++/CLI参照クラスにはマーシャリングは必要ありません。文字列^をポインタo文字列(char *の代わりに)として使用し、配列^を管理対象配列へのポインタとして使用します。

ラッパーをまったく使用する必要はありません。クラスを管理参照(refクラス)として宣言し、ITクラスが.NETクラスなので.NET側から呼び出すことができます。

+3

うわー、あなたは怒っているようです。 –

+1

downvoteは私のものではなく、私は技術的に間違った答えをdownvoteだけです。あなたのことは正しいですが、私はただあなたの声を聞いてほしいと思っていました。そして私に怒らないでください、私は話題をかなりよく知っています:) –

+0

はい。 C++/CLIは、MSからの愛を強く受けなければなりません。ドキュメントは不可解であり、C++のすべての欠点、.NETの癖、両者を混ぜ合わせることによる奇抜な振る舞いを得ることができます。それは頭痛のレシピです。しかし、このタグの質問の3/4は、文字列マーシャリングに関するものです。 - \ –

関連する問題