(p/invoke)用属性 封装 指针型变量

_lee_chong 2012-12-27 07:32:48
有类似以下两个c++结构

struct Student
{
char* name;
float height;
School* pSchool;
}
struct School
{
char* name;
Student* pStudent;
}

因为两个结构互相指向,如果按我以前的方式(如下)的话,其中student 和 school两者间的指向,因每次 非托管指针转托管结构或者托管结构转非托管指针,都在内存中重新分配的内存假如由student.school只能拿到非托管内存中的School无法对应到我已有托管内存中的School,很麻烦

[StructLayout(LayoutKind.Sequential,Pack=1,CharSet=CharSet.Ansi)]
class Student
{
string name;
float height;
IntPtr school;
}

于是我改成如下方式

unsafe class School
{
public School() { }
public School(IntPtr pSchool) { this.pSchool = pSchool; }
public IntPtr pSchool;//指向非托管内存的数据
//省略
}
unsafe class Student
{
public Student() { }
public Student(IntPtr pStudent) { this.pStudent = pStudent; }
public IntPtr pStudent;//指向非托管内存的数据

#region 指向非托管 数据结构 各成员的指针
private char* * pName
{
get { return (char**)((Int32)pStudent + 0); }
}
private float * pHeight
{
get { return (float*)((Int32)pStudent + 4); }
}
private void* * pSchool
{
get { return (void**)((Int32)pStudent + 8); }
}
#endregion

#region 获取 非托管内存 中各成员数据
public string Name
{
get { return Marshal.PtrToStringAnsi((IntPtr)(*pName)); }
set { *pName = (char*)Marshal.StringToHGlobalAnsi(value); }
}
public float Height
{
get { return *pHeight; }
set { *pHeight = value; }
}
public School MySchool
{
get
{
School reuslt = new School((IntPtr)(*pSchool));
return reuslt;
}
set
{
*pSchool = (void*)value.pSchool;
}
}
#endregion
}

以上,这样做虽然解决了问题且一直操作的也只是一开始Dll中初始化的数据,但是毕竟那个unsafe,还有代码里的指针头有点疼;大家有没有更好的,更像c#的方式解决这种问题的;
...全文
139 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
_lee_chong 2012-12-27
  • 打赏
  • 举报
回复
这只是例子,事实上,项目里有7个类似的结构,互相指来指去,有个把结构30几个成员,各种数据类型,光是计算成员便宜地址都头疼了....

110,568

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧