1

私はC#プログラミングが初めてです。.NET インターフェイスから呼び出したい関数が c にあります。そこで、この関数用の dll を作成しました。この時点まで、すべてがうまくいきました。この関数は、ペアの配列の配列である入力引数を取ります。

typedef pair<int,float> Node;
typedef Node** DATA;

c 関数の関数プロトタイプは次のとおりです。

void Train(DATA X, float* Y, float* W);

この関数を .NET インターフェイスで使用するには、まず、2 つの配列にあるデータをノード タイプに変換する必要があります。何かのようなもの :

DATA D = new Node*[2];
D[0] = new Node[5];
D[1] = new Node[2];
for(int i = 0 ; i < 5 ; i++){
    D[0][i].first = i;
    D[0][i].second = i+5;
}
for(int i = 0 ; i < 2 ; i++){
    D[1][i].first = i;
    D[1][i].second = i+5;
}

ここで、このノード (またはペア) 型を c# で定義し、ノードの 2-D 配列への参照を c dll に渡す方法を教えてください。

4

1 に答える 1

0

C コードのペアのメモリ レイアウトに依存しますが、C# で定義できます。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
public struct pair
{
    [MarshalAs(UnmanagedType.I4)]
    public int first;
    [MarshalAs(UnmanagedType.R8)]
    public double second;
}

そのように使用します:

    [DllImport("mydll.dll")]
    static extern void callMyDll(pair** mypair);

(ポインターは、/unsafe オプションを使用して c# で使用できます)

また

    [DllImport("mydll.dll")]
    static extern void callMyDll(pair[] mypair);

(これは、「MarshalAs」属性で指定したメモリ マッピングを使用して、マネージド メモリをアンマネージド メモリにコピーします => より安全です)

編集:ポインターをできるだけ渡さないようにします: C# でインスタンス化されたオブジェクトのアドレスは変更される可能性があります... または「固定された」キーワード リファレンスを参照してください

edit2:「ペア」が (仮想テーブルを持つ) C++ クラスであり、構造体ではない場合void* vtableAddress;、C# 定義でそのメンバーの先頭に a を追加する必要があります。理由を知りたい場合は、仮想テーブルメカニズムに関する詳細なドキュメントを参照してください (C++ および仮想呼び出しを使用するほとんどすべてのコンパイル済み言語で使用されます)。

于 2013-10-30T18:40:49.520 に答える