質問

C ++には次の構造体があります:

#define MAXCHARS 15

typedef struct 
{
    char data[MAXCHARS];
    int prob[MAXCHARS];
} LPRData;

そして、これらの構造の3つの配列を取得するためにp / invokingしている関数:

void GetData(LPRData *data);

C ++では、次のようにします。

LPRData *Results;
Results = (LPRData *)malloc(MAXRESULTS*sizeof(LPRData));
GetData( Results );

そしてそれはうまく動作しますが、C#では動作するように思えません。 次のようなC#構造体を作成しました。

public struct LPRData
{

    /// char[15]
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
    public string data;

    /// int[15]
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
    public int[] prob;
}

そして、それらのうち3つの配列(およびそれらのすべてのサブ配列)を初期化し、これに渡す場合:

GetData(LPRData[] data);

成功して戻りますが、LPRData配列のデータは変更されていません。

3つのLPRDataのサイズの生のバイト配列を作成し、次のような関数プロトタイプに渡しました:

GetData(byte [] data);

しかしその場合、「データ」を取得します;最初のLPRData構造からの文字列、ただし「prob」を含むその後同じLPRDataの配列。

これを適切に処理するためのアイデアはありますか?

役に立ちましたか?

解決

構造体のデクローレーションにいくつかの属性を追加してみます

[StructLayout(LayoutKind.Sequential, Size=TotalBytesInStruct),Serializable]
public struct LPRData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;

/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}

*注TotalBytesInStructは変数を表すことを意図していません

JaredParは、IntPtrクラスを使用するのが役立つ可能性があることも正しいですが、PInvokeを使用してからかなり時間が経ったのでさびています。

他のヒント

ポインターを扱うときの1つのトリックは、IntPtrを使用することです。その後、ポインターでMarshal.PtrToStructureを使用し、構造のサイズに基づいて増分して結果を取得できます。

static extern void GetData([Out] out IntPtr ptr);

LPRData[] GetData()
{
    IntPtr value;
    LPRData[] array = new LPRData[3];
    GetData(out value);
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = Marshal.PtrToStructure(value, typeof(LPRData));
        value += Marshal.SizeOf(typeof(LPRData));
    }
    return array;
}

PInvoke Interop Assistantが役立つ場合があります。 http://clrinterop.codeplex.com/releases/view/14120

同様のトピックがこの質問と、結論は、名前付きパラメーター CharSet CharSet.Ansi に設定する必要があるということでした。そうでなければ、 char 配列の代わりに wchar_t 配列を作成します。したがって、正しいコードは次のようになります。

[Serializable]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct LPRData
{
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
    public string data;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
    public int[] prob;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top