2017-08-27 24 views
0

C#では、構造体のstruct配列でP/Invokeを実行する方法は?C#構造体の構造体配列をP/Invokeするには?

Cラングは、構造体は以下の通りです定義された...

struct 'OuterStruct' 
    int outerId 
    InnerStruct[10] innerStruct 
struct 'InnerStruct' 
    int innerId 
    char[32] name 

そしてCラングは、関数を定義している:

int ClangFunc(OuterStruct* arg) 

'ClangFuncは' '引数' に値を設定されています。私は、C#から 'ClangFunc' と呼ぶ

...

[DllImport("makefromclang.dll", EntryPoint="ClangFunc")] 
public static extern int ClangFunc(IntPtr arg); 

[StructLayout(LayoutKind.Sequential)] 
public struct OuterStruct 
{ 
    public int outerId; 
    [MarshalAs(UnmanagementType.ByValArray, SizeConst=10)] 
    public InnerStuct[] innerStruct; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct InnerStruct 
{ 
    public int innerId; 
    [MarshalAs(UnmanagementType.ByValTStr, SizeConst=32)] 
    public string name; 
} 

/* caller */ 
OuterStruct outerStruct = new OuterStruct(); 
IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(outerStruct)); 
Marshal.StructureToPtr(outerStruct, ptr, false); 
int result = ClangFunc(ptr); 
OuterStruct resultStruct = (OuterStruct)Marshal.PtrToStructure(ptr, typeof(OuterStruct)); 

コールClangFuncが成功しています。 OuterStruct.outerId and OuterStruct.innerStruct[0].innerId

結果は、収集値が設定されている。(上記resultStruct値で)

しかしOuterStruct.innerStruct[0].nameは、なぜnull?です。

""(空文字列)またはShift_JIS文字列が必要です。 nullの値を設定する方法はありません。

+0

CharSet = CharSet.AnsiからInnerStructのStructLayoutを追加します。 – Soonts

+1

引数は '[In、Out] ref OuterStruct arg'でなければなりません。 [Out]属性は、マーシャリングされた構造体の内容をコピーする必要があることをpinvoke marshallerに伝えるために必要です。不足しているCallingConvention.Cdeclは非常に疑わしいです。これらのどれも問題を解決するためには必ずしも保証されていません。C言語でいくつかの単体テストを書いて、意図したとおりに機能するようにしてください。 –

答えて

0

ありがとうございます。

問題は、char []に設定された値がShift_JIS charsetであることです。 .NETがchar []をstringに変換すると、文字セットは考慮されませんでした。 その結果、文字列の値が破損し、デバッガにNULL文字列値があるようです。

この問題を解決するために、構造体にマップされた文字列をbyte []に​​変更し、byte []をstringに変換しました。

// [MarshalAs(UnmanagementType.ByValTStr, SizeConst=32)] 
// public string name; 
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.ByValTStr, SizeConst=32)] 
public byte[] name; 


string str = System.Text.Encoding.GetEncoding("Shift_JIS").GetString(name); 
関連する問題