我在正在构建的项目中使用pinvoke
。
我需要从C中的函数获取数据,该函数获取指向结构的指针。
在我的c#中,我做了一个具有适当属性的类(layountkind.sequntial)。
在我做的功能之前:
mystruct str=new mystruct();
str.Data=new byte[14];
func(str);
我在函数中填充结构但是当它退出函数时,类的实例没有填充c中的值,我在退出c函数之前检查指针的内容它有正确的价值观。 以下是该功能的原型:
[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)]
void func([MarshalAs(UnmanagedType.LPStruct)] mystruct str);
我在C#中的结构:
[StructLayout(LayoutKind.Sequential)]
public class mystruct
{
public ushort familiy;
[MatshalAs(UnmanagedType.ByValArray,SizeConst=14)]
public byte [] data;
}
C中的函数和结构:
struct sockaddr{
unsigned short familiy;
char data [14];
};
void func(struct sockaddr *info)
{
int i;
char buffer[100]
recvfrom(sockfd,buffer,0,info,&i);//assume i have a global varible sockfd and it is an open socket
}
我如何解决我的问题?
答案 0 :(得分:2)
p / invoke声明不正确。默认编组仅为In
。但是你需要Out
编组。否则,marshaller不会尝试将非托管函数的数据集编组回托管类。
所以你可以通过声明这样的函数来解决问题:
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void func([Out] mystruct str);
我个人认为使用C#结构会更加惯用。我这样声明:
[StructLayout(LayoutKind.Sequential)]
public struct mystruct
{
public ushort family;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=14)]
public byte[] data;
}
然后功能变为:
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern void func(out mystruct str);
电话很简单:
mystruct str;
func(out str);