基本情况大致如下:程序是用于一款工业CCD相机的视频采集(就是实现在PC上看到相机拍摄的视屏并作简单操作)。相机厂商提供一套用于VC的开发包,包括 dll等文件 和几个例程,现在手头的软件是前人在 一个例程的基础上编写的。当时拿到这个程序时是可以基本正常的实现设计功能的(但是退出程序时会报错)。前一段时间由于病毒 重装了系统。现在再运行这个程序 却不能正常使用了,在连接相机时会提示下面的错误。“Error:
  The  value of ESP was not properly saved aross a function call. This is usually a result of ......."
对于这种现象,有可能是什么原因造成的呢?希望专家们帮忙分析下。PS:
出错的位置是:Result=Camera.Connect(&GuidUsed,this->m_hWnd);其中Camera是CFGCamera类的一个对象 而CFGCamera::Connect 定义如下:
CFGCamera::Connect 
C++-Syntax: 
 
UINT32 Connect(UINT32HL *pGuid,void* IsoContext=NULL); 
 
Description: 
Connects this object with a real camera connected to the system via FireWire. The camera is selected 
by a unique GUID. When starting image acquisition the application can activate a notification scheme 
to be informed when new images have arrived.  
To figure out which object has transferred an image an IsoContext can be specified (and retrieved). 
 
Return Value: 
0 (FCE_NOERROR) on success, error code otherwise. 
 
Parameters: 
 
Type       Name        IO       Description UINT32HL*  pGuid       In       Pointer to a GUID that contains the exact GUID of the real FireWire 
camera this object shall be connected to. 
void*     IsoContext   In       On notification for a new frame this context is posted to the application.If the function <FGInitModule> has been called with an argument and the flags parameter of the argument contained an asserted bit FGIF_ISOCONTEXTISHWND then the notification for a received 
frame is posted to a window with the handle <IsoContext>. 
出错以后返回值RESLUT是 1021 The object is not connected to a real target。
而在运行到此之前,因为需要获取相机列表已经相机名称,已经使用过CFGCamera::Connect 函数,并且连接相机成功 而且随后还使用相应函数 获取相机名称也没有问题。那一段程序代码是:
Result=FGCamera.Connect(&NodeInfo[i].Guid);        if(Result==FCE_NOERROR)
{
            //获得摄像机名
FGCamera.GetDeviceName(pCameraInfo->DeviceName,sizeof(pCameraInfo->DeviceName));
    
//断开摄像机连接
FGCamera.Disconnect(); //摄像机名写入显示字符串
wsprintf(DisplayName,"%s",pCameraInfo->DeviceName);
         
//写入列表
Ix=pList->AddString(DisplayName);
    
//设置列表框项指针
pList->SetItemDataPtr(Ix,pCameraInfo);
} 出错后我查看了相应的NodeInfo[i].Guid 与 GuidUsed值 都没有问题,都是正确的相机ID。(GuidUsed其实就是双击列表时传递过来的相应的NodeInfo[i].Guid 值)为什么同一个函数不同地方一个出错一个正常呢。。本人对VC了解的不是太多,也希望专家指教一下。如有必要 我随后会贴出其他相关代码。 

解决方案 »

  1.   

    这个错误看起来是函数的调用约定在声明中与实际实现不符,你试试在Connect函数声明前面加上__stdcall、__cdecl、__thiscall等,每种都试一下,看看哪种没有错误。
      

  2.   


    首先非常感谢您的回答。但是为什么会出现前后两次调用 一次正常一次出错呢? 
    如果要在Connect 函数声明前加上_stdcall、__cdecl、__thiscall我应该在哪个位置添加呢?
    此外我如果将工程的Calling convention设置 设成_stdcall、__cdecl、__thiscall作相应测试 是不是可以达到类似的测试效果?但是我尝试了这三种设置 后错误依然存在
      

  3.   

    可能是你两次调用connect之间调用的其他函数没有恢复好堆栈
    第二次调用connect之前调用的是什么函数
      

  4.   

    具体过程是这样的:首先以下代码是view类中的OnFileDevice函数的部分内容,出错位置以后的先省略了。。UINT32HL GuidUsed; //设备选择对话框
    CDlgDeviceSelection DlgDevice;

    if(DlgDevice.DoModal()==IDOK)
    {
    //选定摄像机
    GuidUsed=DlgDevice.GuidSelected;
        
    //连接摄像机
            Result=Camera.Connect(&GuidUsed,this->m_hWnd);。。我在程序菜单选择 “选择设备”菜单执行上述代码,其中CDlgDeviceSelection 是用来实现设备列表和选择的对话框类,里面比较重要的几个函数如下:
    void CDlgDeviceSelection::OnRefresh() 
    {
    // TODO: Add your control notification handler code here
    //声明FGGetNodeList函数的参数
    FGNODEINFO NodeInfo[10]; //声明设备数,循环变量,LIST控件序号
    UINT32      NodeCnt,i,Ix; //函数返回结果
        UINT32      Result;
        
    //列表框,用于显示设备名
    CListBox   *pList; //像机信息指针
        CAMERAINFO   *pCameraInfo;

    // 获取设备节点列表
    Result=FGGetNodeList(NodeInfo,sizeof(NodeInfo)/sizeof(FGNODEINFO),&NodeCnt);
        if(Result!=FCE_NOERROR)
       MessageBox("获取设备清单出现错误","提示",MB_OK|MB_ICONINFORMATION);
        
    //摄像机对象
        CFGCamera     FGCamera; //摄像机名,用于在list中显示
        char          DisplayName[100];
        
    //分配新结构
        pCameraInfo=new CAMERAINFO; //获得列表指针
    pList=(CListBox*)GetDlgItem(IDC_LIST_DEVICE); if(pList->GetCount!=0)
    pList->ResetContent();
    //循环写入list
    for(i=0;i<NodeCnt;i++)
    {
    //设备GUID
    pCameraInfo->Guid=NodeInfo[i].Guid;
            
    //设备总线拓扑ID
    pCameraInfo->NodeId=NodeInfo[i].NodeId; //设置实际速度
    FGCamera.SetParameter(FGP_PHYSPEED,PS_100MBIT); //连接摄像机
    Result=FGCamera.Connect(&NodeInfo[i].Guid);        if(Result==FCE_NOERROR)
    {
                //获得摄像机名
    FGCamera.GetDeviceName(pCameraInfo->DeviceName,sizeof(pCameraInfo->DeviceName));
        
    //断开摄像机连接
    FGCamera.Disconnect(); //摄像机名写入显示字符串
    wsprintf(DisplayName,"%s",pCameraInfo->DeviceName);
             
    //写入列表
    Ix=pList->AddString(DisplayName);
        
    //设置列表框项指针
    pList->SetItemDataPtr(Ix,pCameraInfo);
    }
    }
    }void CDlgDeviceSelection::OnConnect() 
    {
    // TODO: Add your control notification handler code here

    //列表框
    CListBox        *pList;

    //LIST控件序号
      int              Ix;
        
    //像机信息指针
    CAMERAINFO      *pCameraInfo; //获得列表指针
    pList=(CListBox*)GetDlgItem(IDC_LIST_DEVICE); //返回列表框中选中内容的位置
        Ix=pList->GetCurSel();    if(Ix==-1)
        return; //返回列表框指针
    pCameraInfo=(CAMERAINFO*)pList->GetItemDataPtr(Ix);
        
    //设定对话框返回值
    GuidSelected=pCameraInfo->Guid;
    OnOK();
    }
    [/code]OnRefresh主要是生成已经硬件连接PC的相机列表(connect在此时被调用)。OnConnect主要是选择相机并获取Guid。并返回OnFlieDevice。然后再使用此Guid实际连接时 马上就出错了
      

  5.   

    看了半天,说的好像是访问usb时出错了。对吗?
      

  6.   

    不涉及到USB啊。是个1394口的CCD相机