C# 调用C C++动态库封装结构体,结构体数组
一、 结构体传递
typedef stuct
{
Int osVersion;
Char szVersion[128];
}OSINFO;
//1.获取版本信息(传递结构体指针)
extern “C”_declspec(dllexport) void _stdcall GetVsersionPtr(OSINFO *info);
//2.获取版本信息(传递结构体引用)
extern “C”_declspec(dllexport) void _stdcall GetVsersionRef(OSINFO &info);
可以通过两种方式进行调用
C#
[StructLayout(LayoutKind.Sequential)]
Public struct OSINFO
{
Public int osVersion
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=128)]
Public string szVersion;
}
1.方式一(传入结构体引用),在C#中结构体是以传值的方式传递,类才是以传地址的方式传递,加关键字ref即可。C端传递了两种不同的类型参数,都可以通过引用解决。
[DllImport("EfficiencyCLRWrapper.dll")]
static extern void GetVsersionPtr(ref OSINFO info);
2.方式二(传入IntPtr(平台通用指针))
intPtr pv=Marshal.AllocHGlobal(132);//结构体在使用时一定要分配空间(1*size(int)+128)
Marshal.Writnint32(pv,132);//想内存块中写入数值
If(GetVersionPtr(pv))//直接以非托管内存块地址为参数
{
Console.WriteLine(“osVersion:{0}”,Marshal.ReadInt32(pv,0));
Console.WriteLine(“szVersion:{0}”,Marshal.PtrToStringAnsi((IntPtr)(pv.ToInt32())+4);//移动4个字节
}
Marshal.FreeHGlobal(pv);//处理完记得释放内存
二、 结构体数组传递
C++中方法声明:
public void GetPlanes(plane *planes, int size);
C#中结构体声明:
[StructLayout(LayoutKind.Sequential)]
public struct GPlane
{
public double timestamp;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] normal;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] center;
}
C#中方法声明:
[DllImport(LibFileName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern bool Pvr_getAirGlassPlanes([In, Out]GPlane[] plane, int size);
C#中调用该方法:
int size = 2;
GPlane[] plane = new GPlane[size];
Pvr_getAirGlassPlanes(plane, size);
C#调用CLR动态库,传递结构体经验总结
最新推荐文章于 2024-07-24 12:07:39 发布