我调用第三方的dll来读取设备中的设置,第三方dll中的方法要我给出数据缓冲区地址,和缓冲区长度。执行后,确无法从该缓冲区中取得任何数据,请问原因及处理办法。代码如下:
public override int GetServerNTP(IntPtr hDev, ref string NTPUrl, ref int timezone, ref bool enable, ref int reserve)
        {
            DVSNETClient.DVSNET_NTP_PARAM ntp = new DVSNETClient.DVSNET_NTP_PARAM();
            IntPtr pntp = Marshal.AllocHGlobal(Marshal.SizeOf(ntp));            //Marshal.StructureToPtr(ntp, pntp, true);            //IntPtr pntp = IntPtr.Zero;
            uint len = (uint)Marshal.SizeOf(new DVSNETClient.DVSNET_NTP_PARAM());
            int r = GetServerParam(hDev, (uint)(0x10000 + 224), 0,ref pntp, len);            DVSNETClient.DVSNET_NTP_PARAM ntp = (DVSNETClient.DVSNET_NTP_PARAM)Marshal.PtrToStructure(pntp, typeof(DVSNETClient.DVSNET_NTP_PARAM));
            NTPUrl = new string(ntp.strNTPUrl);
            timezone = (int)ntp.nTimeZone;
            enable = ntp.bEnabled == 1 ? true : false;
            reserve = (int)ntp.dwReserve;
            return r;
        }

解决方案 »

  1.   

    你先保证你是否正确从dll得到数据
      

  2.   

       IntPtr pntp = Marshal.AllocHGlobal(Marshal.SizeOf(ntp));            //Marshal.StructureToPtr(ntp, pntp, true);            //IntPtr pntp = IntPtr.Zero;
                uint len = (uint)Marshal.SizeOf(new DVSNETClient.DVSNET_NTP_PARAM());
                int r = GetServerParam(hDev, (uint)(0x10000 + 224), 0,ref pntp, len);//这句话有问题
    如果用ref intptr 的话,c++相当于** , 意思是这个地址,是由dll方面创建....
    改成intptr 试试,另外看看c++如何调用的?
      

  3.   

    我将ref 去掉,代码修改如下:public override int GetServerNTP(IntPtr hDev, ref string NTPUrl, ref int timezone, ref bool enable, ref int reserve)
            {
                DVSNETClient.DVSNET_NTP_PARAM ntp = new DVSNETClient.DVSNET_NTP_PARAM();
                IntPtr pntp = Marshal.AllocHGlobal(Marshal.SizeOf(ntp));            //Marshal.StructureToPtr(ntp, pntp, true);            //IntPtr pntp = IntPtr.Zero;
                uint len = (uint)Marshal.SizeOf(new DVSNETClient.DVSNET_NTP_PARAM());
                int r = GetServerParam(hDev, (uint)(0x10000 + 224), 0, pntp, len);            ntp = (DVSNETClient.DVSNET_NTP_PARAM)Marshal.PtrToStructure(pntp, typeof(DVSNETClient.DVSNET_NTP_PARAM));
                NTPUrl = new string(ntp.strNTPUrl);
                timezone = (int)ntp.nTimeZone;
                enable = ntp.bEnabled == 1 ? true : false;
                reserve = (int)ntp.dwReserve;
                return r;
            }
    可是一样无法得到结构体中的数据
      

  4.   

    c++原型如下:int __stdcall DVSNET_GetServerParam(HANDLE hServer,unsigned long dwCmd,unsigned long nChannel,void *pParam,unsigned long dwParamSize,unsigned long nStreamno = 0);
    对应的在我的代码中: public static extern int DVSNET_GetServerParam(IntPtr hServer, uint dwCmd, uint nChannel, IntPtr pParam, uint dwParamSize,uint nStreamno);
    调用:public override int GetServerParam(IntPtr hDev, uint dwCmd, uint nChannel, IntPtr pParam, uint dwParamSize)
            {          
                return  DVSNETClient.DVSNET_GetServerParam(hDev,dwCmd,nChannel,pParam,dwParamSize,0);
            }
      

  5.   

    c++调用是dll封装好的,没办法知道,不过有demo是运行正常的。
    我现在的问题是调用dll的函数返回值明显是执行成功的,但是我没办法从我指定的缓冲区中得到需要的数据,我怀疑是不是内存的开辟有问题?
      

  6.   

    demo里都一样是调用这个dll的,只不过调用是用c++ 写的
    比如:ZeroMemory(&m_TimePara,sizeof(DVSNET_SERVERTIME_PARAM));
    COleDateTime CurTime = COleDateTime::GetCurrentTime();
    m_TimePara.nYear = CurTime.GetYear();
    m_TimePara.nMonth = CurTime.GetMonth();
    m_TimePara.nDay = CurTime.GetDay();
    m_TimePara.nWeek = CurTime.GetDayOfWeek();
    m_TimePara.nHour = CurTime.GetHour();
    m_TimePara.nMinute = CurTime.GetMinute();
    m_TimePara.nSecond = CurTime.GetSecond();
    DVSNET_SetServerParam(m_hServer,SET_DVS_TIME,0,&m_TimePara,sizeof(DVSNET_SERVERTIME_PARAM));
    ((CButton *)GetDlgItem(IDC_RADIO_SYNPC))->SetCheck(0);
    ((CButton *)GetDlgItem(IDC_RADIO_NOCHANGE))->SetCheck(1);
    if(0 == DVSNET_GetServerParam(m_hServer,GET_DVS_TIME,0,&m_TimePara,sizeof(DVSNET_SERVERTIME_PARAM)))
    {
    m_stDate = COleDateTime(m_TimePara.nYear,m_TimePara.nMonth,m_TimePara.nDay,12,0,0);
    m_stTime = COleDateTime(2007,1,1,m_TimePara.nHour,m_TimePara.nMinute,m_TimePara.nSecond);
    UpdateData(FALSE);
    }
      

  7.   

    m_TimePara 是DVSNET_SERVERTIME_PARAM结构的实例 c++中通过&m_TimePara便可获得其地址,但在c#中我的代码是否有错误呢?我的代码部分如下: DVSNETClient.DVSNET_NTP_PARAM ntp = new DVSNETClient.DVSNET_NTP_PARAM();
                IntPtr pntp = Marshal.AllocHGlobal(Marshal.SizeOf(ntp));
      

  8.   

    oletime 在你的C# 里怎么转的?