C# 调用 非托管C++dll库 求帮忙翻译谢谢 成功后再追加分数

Ival 2019-06-20 01:02:09
项目WINFORM调用双目摄像头.c#在调用非托管C++dll库时,在调用函数获取图片时头大了,求高手帮忙翻译. 上代码
头文件
/*
Function: DVTLDCam_GetImage();
Description: Get normal image after event returned EVENT_OK, 3 image types supported, refer to LD_IMG_TYPE .
Parameters:
hCam -- Handle of the opened camera.
nImageType -- image type, refer to LD_IMG_TYPE.
pBuff -- buffer to receive image data, recommended buffer length is width*height*5. (640*480*5)
nBuffLen -- length of buffer
pRetLen -- returned data length.

return:
0 -- No error
others-- Error
*/
DVTLDCAMSDK_API int STDCALL DVTLDCam_GetImage(HANDLE hCam, int nImageType, unsigned char* pBuff, int nBuffLen, int *pRetLen);


c# 调用
[StructLayoutAttribute(LayoutKind.Sequential,CharSet = CharSet.Ansi, Pack = 1)]
public struct ByteBuff
{
/// unsigned char[30]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 1536000)]
public byte[] pBuff;
}

[DllImport("DVTLDCamSDK.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
internal static extern int DVTLDCam_GetImage(IntPtr hCam, Int32 nImageType, IntPtr pBuff, Int32 nBuffLen, ref Int32 pRetLen);


public void EventCallback(int event_id)
{
int nRet;
int nLen =1536000;
int nRetLen = 0;
int nFaceW = 0, nFaceH = 0;
string strPath = GetFilePath();
string savePath = string.Empty;
string saveFacePath = string.Empty;
ByteBuff pBuff = new ByteBuff();

if (event_id == 1)
{
int nSelect = -1;
nSelect = ImageFormatIndex;
nRet = DVTLDCam_GetImage_Delegate(m_hCam, nSelect, ref pBuff, nLen, ref nRetLen);

if (nRet != 0)
{
MessageBox.Show("Get image error");
goto done;
}
if (nSelect == 0) //CameraDev.LD_IMG_TYPE.IMG_RGB24
{
savePath = strPath + ".bmp";
此处pBuff.pBuff byte[] 始终是1536000 全部是0
WriteBMPFile2(savePath, pBuff.pBuff, nRetLen);
}
else
{
if (nSelect == 1) //CameraDev.LD_IMG_TYPE.IMG_JPG
{
savePath = strPath + ".jpg";
}
else if (nSelect == 2) //CameraDev.LD_IMG_TYPE.IMG_RGB24_BASE64
{
savePath = strPath + "_rgb.txt";
}
else if (nSelect == 3) //CameraDev.LD_IMG_TYPE.IMG_JPG_BASE64
{
savePath = strPath + "_base64.txt";
}

WriteFile(savePath, pData, nRetLen);
}


MessageBox.Show("Detect success");
}
else
{
MessageBox.Show("Detect error, event = " + event_id.ToString());
}

done:

if (event_id == CameraDev.EVENT_CALLCED)
{

}
else
{
StartDetect();
}
}
private int DVTLDCam_GetImage_Delegate(IntPtr hCam, Int32 nImageType, ref CameraDev.ByteBuff pBuff, Int32 nBuffLen, ref Int32 pRetLen)
{
System.IntPtr IntPtrBuff = IntPtr.Zero;
try
{
int param_size = Marshal.SizeOf(pBuff);
IntPtrBuff = Marshal.AllocHGlobal(param_size);

Marshal.StructureToPtr(pBuff, IntPtrBuff, false);
int ret = CameraDev.DVTLDCam_GetImage(hCam, nImageType, IntPtrBuff, nBuffLen, ref pRetLen);
pBuff = (CameraDev.ByteBuff)Marshal.PtrToStructure(IntPtrBuff, typeof(CameraDev.ByteBuff));

return ret;
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
}
finally
{
try
{
Marshal.FreeHGlobal(IntPtrBuff);
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
}
}
return 0;
}[code=c#][/code]
...全文
144 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ival 2019-06-25
  • 打赏
  • 举报
回复
引用 13 楼 zijiang001 的回复:
1、如果去掉[Out]程序没有异常,nRetLen长度有值,但是pBuff是空数据,基本说明pBuff没有写进去 2、不去掉[Out]程序异常崩溃,很可能pBuff长度短了,写入内存异常,可以在步骤1上面看下nRetLen的长度输出 3、可能DLL的问题,用Demo程序试试 能想到的暂时就这么多,祝你顺利!
谢谢,联系了厂商,搞定的,他们返回的数据是特殊的字节数组,转成BMP格式的图片要特殊处理一下.不管怎样还是谢谢.
OrdinaryCoder 2019-06-20
  • 打赏
  • 举报
回复
DVTLDCam_GetImage(IntPtr hCam, Int32 nImageType, byte[] buffer, Int32 nBuffLen, Int32[] pRetLen);
zijiang001 2019-06-20
  • 打赏
  • 举报
回复
DVTLDCam_GetImage(IntPtr hCam, Int32 nImageType, [Out]byte[] buffer, Int32 nBuffLen, ref Int32 pRetLen);试试
Ival 2019-06-20
  • 打赏
  • 举报
回复
自己顶,求大神帮忙!
zijiang001 2019-06-20
  • 打赏
  • 举报
回复
1、如果去掉[Out]程序没有异常,nRetLen长度有值,但是pBuff是空数据,基本说明pBuff没有写进去 2、不去掉[Out]程序异常崩溃,很可能pBuff长度短了,写入内存异常,可以在步骤1上面看下nRetLen的长度输出 3、可能DLL的问题,用Demo程序试试 能想到的暂时就这么多,祝你顺利!
zijiang001 2019-06-20
  • 打赏
  • 举报
回复
数组传值默认是引用地址的,你可以去掉[Out]试试看,挂掉的情况在windows日志看一下可能原因
Ival 2019-06-20
  • 打赏
  • 举报
回复
引用 9 楼 zijiang001 的回复:
看两个参数吧 图片存储在pBuff里面所以加上[Out]修饰,文档上说 pBuff推荐推荐长度是640*480*5 图片长度存储在nRetLen里面 如果nRetLen返回值 > 0的话,说明应该调用成功 从pBuff里面copy nRetLen长度的数据在存下来,应该就是图片了
加上 OUT 或者REF修饰符,程序直接挂掉
Ival 2019-06-20
  • 打赏
  • 举报
回复
引用 9 楼 zijiang001 的回复:
看两个参数吧 图片存储在pBuff里面所以加上[Out]修饰,文档上说 pBuff推荐推荐长度是640*480*5 图片长度存储在nRetLen里面 如果nRetLen返回值 > 0的话,说明应该调用成功 从pBuff里面copy nRetLen长度的数据在存下来,应该就是图片了
nRetLen 确实是返回的是大于0的,说明是返回成功了,问题就是这个byte[] 全部都是0,完全不是一张图片.
zijiang001 2019-06-20
  • 打赏
  • 举报
回复
看两个参数吧 图片存储在pBuff里面所以加上[Out]修饰,文档上说 pBuff推荐推荐长度是640*480*5 图片长度存储在nRetLen里面 如果nRetLen返回值 > 0的话,说明应该调用成功 从pBuff里面copy nRetLen长度的数据在存下来,应该就是图片了
Ival 2019-06-20
  • 打赏
  • 举报
回复
引用 7 楼 stherix 的回复:
[quote=引用 5 楼 Ival 的回复:] [quote=引用 4 楼 stherix 的回复:] 就把IntPtr pBuff改成byte[] pBuff就可以了,调用前事先需要先申请内存
能给详细点的代码吗? 如果改成byte[] 程序直接挂掉了[/quote] byte[] pBuff =new byte[足够大]; DVTLDCam_GetImage_Delegate(m_hCam, nSelect, pBuff, nLen, ref nRetLen);[/quote] 还是没用.返回的是个空的 byte[1536000] 不是图片.
stherix 2019-06-20
  • 打赏
  • 举报
回复
引用 5 楼 Ival 的回复:
[quote=引用 4 楼 stherix 的回复:] 就把IntPtr pBuff改成byte[] pBuff就可以了,调用前事先需要先申请内存
能给详细点的代码吗? 如果改成byte[] 程序直接挂掉了[/quote] byte[] pBuff =new byte[足够大]; DVTLDCam_GetImage_Delegate(m_hCam, nSelect, pBuff, nLen, ref nRetLen);
Ival 2019-06-20
  • 打赏
  • 举报
回复
引用 2 楼 zijiang001 的回复:
DVTLDCam_GetImage(IntPtr hCam, Int32 nImageType, [Out]byte[] buffer, Int32 nBuffLen, ref Int32 pRetLen);试试
如果改成byte[] 程序直接挂掉了
Ival 2019-06-20
  • 打赏
  • 举报
回复
引用 4 楼 stherix 的回复:
就把IntPtr pBuff改成byte[] pBuff就可以了,调用前事先需要先申请内存
能给详细点的代码吗? 如果改成byte[] 程序直接挂掉了
stherix 2019-06-20
  • 打赏
  • 举报
回复
就把IntPtr pBuff改成byte[] pBuff就可以了,调用前事先需要先申请内存

110,533

社区成员

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

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

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