2017-08-27 68 views
0

在C#中,如何在结构体struct struct中调用P/Invoke?C#如何P /结构数组中调用struct?

ç朗定义结构是低于...

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

与C朗定义函数:

int ClangFunc(OuterStruct* arg) 

'ClangFunc' 设置值 'ARG'。

我称之为 'ClangFunc' 从C#...

[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].namenull,为什么?

我期待“”(空字符串)或任何Shift_JIS字符串。没有办法设置null的值。

+0

将CharSet = CharSet.Ansi添加到InnerStruct的StructLayout。 – Soonts

+1

参数应该是'[In,Out] ref OuterStruct arg'。 [Out]属性有必要告诉pinvoke编组人员,它需要将编组结构内容复制回来。缺少的CallingConvention.Cdecl非常可疑。这些都不能保证解决问题,你最好在C中编写一些单元测试,以确保该功能按预期工作。 –

回答

0

谢谢大家。

问题是在char []中设置的值是Shift_JIS字符集。 .NET将char []转换为字符串时,它不考虑字符集。 因此,字符串值已损坏,调试器似乎具有空字符串值。

为解决此问题,我将映射到结构的字符串修改为byte [],并将byte []转换为字符串。

// [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);