(图像采集)C++转C#如何实现 40C

我在使用第三方的图像采集代码库(C++编码),想转成C#,结果不知如何实现?

我尽可能提供更加详细的信息,期待大神能够帮忙解决。

1)第三方提供的图像采集头文件:--------------------------------------
#ifndef ATCAM_H
#define ATCAM_H

#ifdef ATCAM_EXPORTS
#define ATCAM_API __declspec(dllexport)
#else
#define ATCAM_API __declspec(dllimport)
#endif

//Parameters Defines
#define PARA_CAM_INT 0x5001
#define PARA_CAM_GAIN 0x5002

//Acquire Information
typedef struct _AtInfo
{
int CodeAcq; //Code Acquire
void * pData; //Data Pointer
void * Context; //Context For User Application
}AtInfo,*PAtInfo;

//CallBack Function
typedef void (__stdcall *AtCallBack)(AtInfo * pInfo);

#ifdef __cplusplus
extern "C" {
#endif

//Get Device Count
ATCAM_API int __stdcall AtCamDev( int * count );
//Open the Selected Device

ATCAM_API int __stdcall AtCamOpen( int devNo );
//Close the Selected Device
ATCAM_API int __stdcall AtCamClose( int devNo );
//Get Device Parameters
ATCAM_API int __stdcall AtCamGet( int devNo, int para, void * buf );

//Set Device Parameters
ATCAM_API int __stdcall AtCamSet( int devNo, int para, int * buf );
//Start Acquire
ATCAM_API int __stdcall AtCamStart( int devNo, PAtInfo pInfo, AtCallBack callBack );
//Stop Acquire
ATCAM_API int __stdcall AtCamStop( int devNo );
#ifdef __cplusplus
}
#endif

#endif

2)C++中图像采集实现:----------------------------------------------
头文件中的定义:
AtInfo m_sInfo;
static void __stdcall AcqCallBack(PAtInfo pInfo);

在*.cpp文件中

AtCamStart(0,&m_sInfo,AcqCallBack);

//采集回调函数
void CAtCamDemoDlg::AcqCallBack(PAtInfo pInfo)
{
//获取上下文信息,发送更新消息
CAtCamDemoDlg * pDlg = (CAtCamDemoDlg*)pInfo->Context;
::PostMessageW( pDlg->m_hWnd,WM_ACQUIRED,(WPARAM)pInfo,pInfo->CodeAcq );
}

/采集更新消息函数
LONG CAtCamDemoDlg::OnAcquired(WPARAM wParam, LPARAM lParam)
{
//未启动采集,返回
if( false == m_bAcquiring )
return 0;

//采集结果判断
int rc = (int)lParam;
if( 0!=rc )
{
    OnBnClickedBtnRun();
    MessageBox(_T("采集失败!"),_T("错误"),MB_OK);
}
else
{
    //成功采集,拷贝数据,更新显示
    memcpy(m_pDataBuf, m_sInfo.pData, IMAGES);
    if( false == m_ctrlImage.m_bUpdating )
        m_ctrlImage.UpdateImage(m_pDataBuf);
}
return 0;

}

3)我在C#中的定义:----------------------------------------------------
public struct AtInfo
{
public int CodeAcq;
public IntPtr pData;
public IntPtr Context;
};

    //grab start
    [DllImport("AtCam.dll", EntryPoint = "AtCamStart")]
    public static extern int AtCamStart(int devNo, out AtInfo pInfo, AtCallback callback);

4)我的实现:----------------------------------------------------------
开始采集
private void Btn_GrabStart_Click(object sender, EventArgs e)
{
if (!camOpened) return;
if (inAcquiring) return;

    int ret = 0;

    ret=OptiMat.AtCamStart(0, out sInfo, AcqCallback);
    textBox1.Text += Environment.NewLine + "Capture Start return: " + ret.ToString();

    inAcquiring = true;

}

回调:
private void AcqCallback(out AtInfo info)
{
AtInfo info0 = new AtInfo();

    info=info0;

    OptiMatImage.PostMessage(hShowMsgWin, OptiMatImage.IMG_MESSAGE, info.CodeAcq, info);

}

消息处理:
protected override void DefWndProc(ref Message m)
{
switch (m.Msg)
{
//接收自定义消息MYMESSAGE,并显示其参数
case OptiMatImage.IMG_MESSAGE:
AtInfo ml = new AtInfo();
ml.pData = m.LParam;
ml.CodeAcq = (m.WParam).ToInt32();

                    ShowImage(ml);

                    break;
            default:
                    base.DefWndProc(ref m);
                    break;
    }

}

图像显示:
private void ShowImage(AtInfo ip)
{
Marshal.Copy(ip.pData, dataBuf, 0, OptiMat.IMAGES);

}
在这一步会出现以下错误:
图片说明

请指出------------------------------------------------------------------
1)哪里出现错误了;
2)我不熟悉这种转换,如何改进比较好?

4个回答

我们公司是做相机的,是提供了一套接口来采集图片数据,我给客户开发过c#程序,先简单在这里写一下吧:

 byte[] pImageData = new byte[nCaptureWidth * nCaptureHeight * (nCaptureBitCount >> 3)];
 KSJApiBase.KSJ_CaptureRgbData(m_nDeviceCurSel, pImageData);

而接口我在调用时候重新进行了声明:

  extern int KSJ_CaptureRgbData(int nChannel, byte[] pRgbData);

我不知道你那边是什么问题,不过你可以参考一下,其实就是把byte*变成了 byte[],之后的其他处理,就是c#内部的问题了。

phenix2009
白色一大坨 回复: 你qq上面怎么不说话了,明明都加上了,到底会不会转
大约一年之前 回复
zaihuan_yu
zaihuan_yu 回复phenix2009: 我也觉得这样不合适,但不知如何转换啊
大约一年之前 回复
phenix2009
白色一大坨 你代码里面直接用了public IntPtr pData;,我觉得不合适,你可以考虑换一下,如果还有问题可以加企鹅聊,四六五六一七七二七,我是做c++方向的,c#懂一点
大约一年之前 回复

你可以将C++的代码封装成dll,然后用C#去调用,如果需要帮助请留言

zaihuan_yu
zaihuan_yu 谢谢,我不知如何封装,其实我只要输入图像就行,如BMP格式;需要我提供C++源代码吗?
大约一年之前 回复

@lengyue2015,需要帮助,我这边要提供啥?

将C++ IplImage 图像用C#读取 需要安装emgucv ,也可以自己实现这个类
https://www.cnblogs.com/hust-yingjie/p/5504748.html

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!