如何使用结构的指针数组定义一个函数作为从C到C的参数#

时间:2013-01-21 22:00:22

标签: c# pinvoke

在C代码中,函数定义如下:

INT WINAPI myFunction(LPCTSTR str1, LPCTSTR str2, INT iNumber,
    LPSTRUCT *lpStruct);

*lpStruct是结构类型的指针数组:

typedef struct myStruct
{
CHAR                    m_s1[64];       
UINT                    m_nS;       
CHAR                    m_s2[8][64];    
UINT                    m_nP;
CHAR                    m_s3[512];

} SomeStruct, *LPSTRUCT;

我需要在C#中调用此外部myFunction,我将SomeStruct定义为:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SomeStruct
{

   [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 64)]
   public string m_s1;             
   public uint m_nS;             
   [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 512)]
   public string m_s2;             
   public uint m_nP;
   [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 512)]
   public string m_s3;
 }

myFunction as:

[DllImport("some.dll")]
public static extern int myFunction(
             string str1,
             string str2,
             int iNumber,
             IntPtr[] lpStruct);

我在C#中初始化IntPtr []:

IntPtr[] lpptr = new IntPtr[iNumber]; 

我知道指针的struct数组有iNumber个元素。

调用此函数没有错误(lpStruct[i]有数字)。但是当我尝试使用:

对指向结构的指针进行Marshal时
SomeStruct st = (SomeStruct )Marshal.PtrToStructure(lpStruct[i], 
    typeof(SomeStruct ));

我收到错误消息:尝试写入只读内存。我不知道这里有什么问题。 C#中的外部函数定义是错误的还是struct的定义错误,或两者兼而有之。

2 个答案:

答案 0 :(得分:0)

尝试将Struct定义为C#

中的类
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class SomeStruct
{

   [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 64)]
   public string m_s1;             
   public UInt32 m_nS;             
   [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 512)]
   public string m_s2;             
   public UInt32 m_nP;
   [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 512)]
   public string m_s3;
}

也可以尝试unt的UInt32

答案 1 :(得分:0)

这个问题缺乏重要的细节,但我希望你需要为数组中的每个IntPtr分配内存。

IntPtr[] lpptr = new IntPtr[iNumber];
for (int i=0; i<iNumber; i++)
    lpptr[i] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SomeStruct)));

显然你应该在完成记忆后释放记忆。