C#调用C++动态库(DLL)数据类型转换

文章详细介绍了如何在C++和C#之间通过DLL接口进行结构体数据的输入和输出,包括结构体嵌套结构体、单个结构体的情况。示例涵盖了SS_CAMERA_INFO_LIST和SS_FRAME_INFO等结构体的使用,以及SS_EnumDevices和SS_GetImageBuffer等接口的调用方法。
摘要由CSDN通过智能技术生成
  1. 情形1:结构体套结构体的数据输入、输出

1.1、C++库的结构体定如下

struct SS_CAMERA_INFO

{

char szCurrentIp[15];

};

struct SS_CAMERA_INFO_LIST

{

unsigned int iDeviceNum;

SS_CAMERA_INFO* pCameraInfo[256];

};

C++的导出接口定义如下

int __stdcall SS_EnumDevices(IN int iCameraType, OUT SS_CAMERA_INFO_LIST* pCameraList);

int __stdcall SS_OpenCamera(IN SS_CAMERA_INFO* pCameraInfo);

1.2、C#对应的结构体定义如下

public struct SS_CAMERA_INFO

{

[MarshalAs(UnmanagedType.LPStr, SizeConst = 15)]

public string szCurrentIp;

};

[StructLayout(LayoutKind.Sequential)]

public struct SS_CAMERA_INFO_LIST

{

public int iDeviceNum;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] // 指定数组尺寸

public SS_CAMERA_INFO[] pCameraInfo;

};

C#引入DLL接口定义如下

[DllImport(@"SsCameraControl.dll", EntryPoint = "#2", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

public static extern int SS_EnumDevices(int iCameraType, IntPtr ptrCameraList);

[DllImport(@"SsCameraControl.dll", EntryPoint = "#14", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

public static extern int SS_OpenCamera(IntPtr ptrCameraInfo);

1.3、接口使用方法如下

//接口SS_EnumDevices()的使用如下:

//申请IntPtr空间,用于存放SDK返回的结构体指针

int size = Marshal.SizeOf(typeof(SS_CAMERA_INFO_LIST));

IntPtr ptrCameraList = Marshal.AllocHGlobal(size);

//调用接口,获取数据

int iRet = SS_EnumDevices(1, ptrCameraList)

//把IntPtr的内存转换到C#结构体的内存

IntPtr ptr = (IntPtr)((UInt32)ptrCameraList + 0 * size);

SS_CAMERA_INFO_LIST cameraList = (SS_CAMERA_INFO_LIST)Marshal.PtrToStructure(ptr, typeof(SS_CAMERA_INFO_LIST));

//其中cameraList变量中,就有从DLL获取出来的数据

Console.WriteLine("cameraList.iDeviceNum=" + cameraList.iDeviceNum);

Console.WriteLine("cameraList.pCameraInfo[0].szCurrentIp=" + cameraList.pCameraInfo[0].szCurrentIp);

//接口SS_OpenCamera()使用如下:

//调用SDK接口

for (int i = 0; i < cameraList.iDeviceNum; i++)

{

IntPtr prtTemp = Marshal.ReadIntPtr(ptrCameraList + Marshal.SizeOf(typeof(IntPtr)) * (i+1));

int iRet = SS_OpenCamera(prtTemp);

}

  1. 情形2:单构体的数据输入、输出

2.1、C++库的结构体定如下

struct SS_FRAME_INFO

{

unsigned char* pBufAddr;

unsigned short nWidth;

unsigned short nHeight;

SsPixeFormat enPixelType;

unsigned int iFrameId;

};

C++的导出接口定义如下

int __stdcall SS_GetImageBuffer(OUT SS_FRAME_INFO *pFrameInfo);

2.2、C#对应的结构体定义如下

internal unsafe struct SS_FRAME_INFO

{

public IntPtr pBufAddr;

public short nWidth;

public short nHeight;

public int enPixelType;

public int iFrameId;

};

C#引入DLL接口定义如下

[DllImport(@"SsCameraControl.dll", EntryPoint = "#9", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

public static extern int SS_GetImageBuffer(IntPtr ptrCameraInfo);

2.3、接口使用方法如下

//接口SS_GetImageBuffer()使用如下:

int size = Marshal.SizeOf(typeof(SS_FRAME_INFO));

IntPtr ptrFrameInfo = Marshal.AllocHGlobal(size);

iRet = SS_GetImageBuffer(ptrFrameInfo);

//把IntPtr的内存转换到C#结构体的内存

IntPtr ptr = (IntPtr)((UInt32)ptrFrameInfo + 0 * size);

SS_FRAME_INFO stFrameInfo = (SS_FRAME_INFO)Marshal.PtrToStructure(ptr, typeof(SS_FRAME_INFO));

//其中stFrameInfo 变量中,就有从DLL获取出来的数据

int iImageSize = stFrameInfo.nWidth * stFrameInfo.nHeight * 3;

byte[] bRgbData = new byte[iImageSize];

int iYuvSize = iImageSize / 2;

byte[] bYuvData = new byte[iYuvSize];

Marshal.Copy(stFrameInfo.pBufAddr, bYuvData, 0, iYuvSize);

  1. 情形3:单构体的数据输入、输出

3.1、C++库的结构体定如下

struct SS_ENUM_VALUE

{

int iCurValue;

int iSupportedNum;

int pSupportValue[SS_MAX_ENUM__NUM];

};

C++的导出接口定义如下

int __stdcall SS_GetEnumValue(IN const char* pStrKey, OUT SS_ENUM_VALUE* pEnumValue);

int __stdcall SS_SetEnumValue(IN const char* pStrKey, IN int iValue);

3.2、C#对应的结构体定义如下

struct SS_ENUM_VALUE

{

public int iCurValue;

public int iSupportedNum;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]

public int[] pSupportValue;

};

C#引入DLL接口定义如下

[DllImport(@"SsCameraControl.dll", EntryPoint = "#7", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

public static extern int SS_GetEnumValue(IntPtr ptrKey, IntPtr ptrEnumValue);

[DllImport(@"SsCameraControl.dll", EntryPoint = "#16", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

public static extern int SS_SetEnumValue(IntPtr ptrKey, int iValue);

3.3、接口使用方法如下

//接口SS_GetEnumValue()使用如下:

IntPtr ptrKey = Marshal.StringToHGlobalAnsi("IsoGain");

int size = Marshal.SizeOf(typeof(SS_ENUM_VALUE));

IntPtr ptrEnumValue = Marshal.AllocHGlobal(size);

//调用接口,获取数据

iRet = SS_GetEnumValue(ptrKey, ptrEnumValue);

//把IntPtr的内存转换到C#结构体的内存

IntPtr ptr = (IntPtr)((UInt32)ptrEnumValue + 0 * size);

SS_ENUM_VALUE stEnumValue = (SS_ENUM_VALUE)Marshal.PtrToStructure(ptr, typeof(SS_ENUM_VALUE));

//其中stEnumValue 变量中,就有从DLL获取出来的数据

for (int i = 0; i < stEnumValue.iSupportedNum; i++)

{

Console.WriteLine("stEnumValue.pSupportValue[i]=" + stEnumValue.pSupportValue[i].ToString());

}

//接口SS_SetEnumValue()使用如下:

IntPtr ptrKey = Marshal.StringToHGlobalAnsi("IsoGain");

int iRet SS_SetEnumValue(ptrKey, 100);

  1. 情形4:单构体的数据输入、输出

4.1、C++库的结构体定如下

struct SS_FLOAT_VALUE

{

float fCurValue;

float fMax;

float fMin;

float fStep;

};

C++的导出接口定义如下

nt __stdcall SS_GetFloatValue(IN const char* pStrKey, OUT SS_FLOAT_VALUE* pFloatValue);

int __stdcall SS_SetFloatValue(IN const char* pStrKey, IN float fValue);

4.2、C#对应的结构体定义如下

public struct SS_FLOAT_VALUE

{

public float fCurValue;

public float fMax;

public float fMin;

public float fStep;

};

C#引入DLL接口定义如下

[DllImport(@"SsCameraControl.dll", EntryPoint = "#8", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

public static extern int SS_GetFloatValue(IntPtr ptrKey, IntPtr ptrFloatValue);

[DllImport(@"SsCameraControl.dll", EntryPoint = "#17", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

public static extern int SS_SetFloatValue(IntPtr ptrKey, float fValue);

4.3、接口使用方法如下

//接口SS_GetFloatValue()使用如下:

IntPtr ptrKey = Marshal.StringToHGlobalAnsi("ExposureTime");

int size = Marshal.SizeOf(typeof(SS_FLOAT_VALUE));

IntPtr ptrFloatValue = Marshal.AllocHGlobal(size);

//调用接口,获取数据

int iRet = SS_GetFloatValue(ptrKey, ptrFloatValue);

//把IntPtr的内存转换到C#结构体的内存

IntPtr ptr = (IntPtr)((UInt32)ptrFloatValue + 0 * size);

SS_FLOAT_VALUE stFloatValue = (SS_FLOAT_VALUE)Marshal.PtrToStructure(ptr, typeof(SS_FLOAT_VALUE));

//其中stFloatValue 变量中,就有从DLL获取出来的数据

Console.WriteLine("stFloatValue.fMax =" + stFloatValue.fMax);

Console.WriteLine("stFloatValue.fMin =" + stFloatValue.fMin);

Console.WriteLine("stFloatValue.fStep =" + stFloatValue.fStep);

Console.WriteLine("stFloatValue.fCurValue =" + stFloatValue.fCurValue);

//接口SS_SetFloatValue()使用如下:

IntPtr ptrKey = Marshal.StringToHGlobalAnsi("ExposureTime");

int iRet SS_SetFloatValue(ptrKey, 108.0f);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mark-puls

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值