DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: wjy13061029975
今日帖子: 7
在线用户: 23
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/11 16:38:18
标题:
海康威视DVR二次开发遇到的问题 浏览:1705
加入我的收藏
楼主: 用SDK处理按文件回放,遇到一个问题,返回的结果中读取的文件大小、开始时间、结束时间的错误的数值。
...
type
  NET_DVR_FIND_DATA = record
    sFileName: Array[0..100-1] of Char;
    struStartTime: NET_DVR_TIME;
    struStopTime: NET_DVR_TIME;
    dwFileSize: LongInt;
  end {NET_DVR_FIND_DATA};
  LPNET_DVR_FIND_DATA = ^NET_DVR_FIND_DATA;
...
type
  NET_DVR_TIME = record
    dwYear: LongInt;
    dwMonth: LongInt;
    dwDay: LongInt;
    dwHour: LongInt;
    dwMinute: LongInt;
    dwSecond: LongInt;
  end {NET_DVR_TIME};
  LPNET_DVR_TIME = ^NET_DVR_TIME;

...
strFile : NET_DVR_FIND_DATA;
...
lnext := NET_DVR_FindNextFile(lFindFile, strFile);

//获取文件名是正确的
kbmMemTB_FielPlay.FieldByName('Filename').AsString :=  PAnsiChar(@strFile.sFileName);
//获取文件大小,虽然有数值,但是是错误的,和官方DEMO获取的数值不一样
kbmMemTB_FielPlay.FieldByName('FileSize').AsInteger := LongInt(strFile.dwFileSize);
iYear := strFile.struStartTime.dwYear;//获取的年份数值也是错误的
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/12/11 16:41:57
1楼:  Char  AnsiChar  WideChar
PChar PAnsiChar PWideChar
一切皆有可能。
正确也是其中一种可能。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/11 16:43:35
2楼: wang_80919: 但是定义的是整形。。。
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/11 16:44:33
3楼:           String MyString;
          if (strFile.dwFileSize < 1024 * 1024)
          {
          iTemp = (strFile.dwFileSize) / (1024);
          MyString = iTemp + "K";
          }
          else
          {
          iTemp = (strFile.dwFileSize) / (1024 * 1024);
          MyString = iTemp + "M   ";
          iTemp = ((strFile.dwFileSize) % (1024 * 1024)) / (1204);
          MyString = MyString + iTemp + "K";
          }
          newRow.add(MyString);          //添加文件大小信息
          newRow.add(strFile.struStartTime.toStringTime());//添加开始时间信息
          newRow.add(strFile.struStopTime.toStringTime()); //添加结束时间信息

-- 这个是官方JAVA的DEMO,看上去也是直接就读取到数值的啊
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/11 16:46:53
4楼: 官方JAVA Demo 的定义:
public static class NET_DVR_FIND_DATA extends Structure
{
  public byte[] sFileName = new byte[100];//文件名
  public NET_DVR_TIME struStartTime;//文件的开始时间
  public NET_DVR_TIME struStopTime;//文件的结束时间
  public int dwFileSize;//文件的大小
}

    public static class NET_DVR_TIME extends Structure {//校时结构参数
        public int dwYear;    //年
        public int dwMonth;    //月
        public int dwDay;    //日
        public int dwHour;    //时
        public int dwMinute;    //分
        public int dwSecond;    //秒

      public String toString() {
          return "NET_DVR_TIME.dwYear: " + dwYear + "\n" + "NET_DVR_TIME.dwMonth: \n" + dwMonth + "\n" + "NET_DVR_TIME.dwDay: \n" + dwDay + "\n" + "NET_DVR_TIME.dwHour: \n" + dwHour + "\n" + "NET_DVR_TIME.dwMinute: \n" + dwMinute + "\n" + "NET_DVR_TIME.dwSecond: \n" + dwSecond;
        }
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/11 16:57:58
5楼: 实时回放、按时间回放、按文件回放、下载、截图都已经处理好了,现在就卡在这里。。。因为某些功能要用到文件的时间作为判断条件。。。
----------------------------------------------
-
作者:
男 yugong23 (yugong23) ▲▲▲▲△ -
普通会员
2017/12/11 23:52:36
6楼: 作者既然用记录指针,就要给该指针分配内存,然后这样访问:
 var p1:LPNET_DVR_TIME;
begin

 new(p1);


kbmMemTB_FielPlay.FieldByName('Filename').AsString :=   p1^.sFileName;
kbmMemTB_FielPlay.FieldByName('FileSize').AsInteger :=  p1^.dwFileSize;

..
end;
----------------------------------------------
-
作者:
男 yugong23 (yugong23) ▲▲▲▲△ -
普通会员
2017/12/11 23:55:24
7楼: 没必要定义LPNET_DVR_TIME,
因为从第一个纪录体内直接引用它,
记录可以直接引用,指针要分配内存
最后记着释放内存
----------------------------------------------
-
作者:
男 421 (421) ★☆☆☆☆ -
盒子活跃会员
2017/12/11 23:56:24
7楼: 1楼给的建议的测试了吗?
sFileName: Array[0..100-1] of AnsiChar
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/12/12 9:34:28
8楼: 看这翻译,怪的没话说了。

一般vc里,dw开头的都是dword类型,你翻译成long?

另外,看兰州的demo
sFileName = new byte[100];如果这个结果能正确,那么就表示filename是ansichar的数组,长度100;

这翻译明显有很多问题。兰州要搞清楚问题,你最好把官方头文件给贴出来。
----------------------------------------------
--
作者:
男 yugong23 (yugong23) ▲▲▲▲△ -
普通会员
2017/12/12 22:53:49
9楼: delphi中:LongInt 就是 Integer 等于 Java 的 Int
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/12 22:55:25
9楼: yugong23: 
1.直接引用strFile.dwFileSize的数值是错误的
2.PAnsiChar(@strFile.sFileName);文件名这里的取出来的字符是正确的

421:
sFileName那里没问题,取出来的字符是正确的

bahamut8348:
贴出来记录的定义,都是官方的

非常感谢大家的解答,但是大家貌似都对sFilename不认可,现在sFilename取出来的字符是正确的。问题主要是sSize和struStartTime、struStopTime,sSize直接取出来的数值是错误的
----------------------------------------------
-
作者:
男 yugong23 (yugong23) ▲▲▲▲△ -
普通会员
2017/12/12 23:15:07
10楼:
作者没有搞清楚, 从delphi 2009 以后 采用 UNICODE,
AnsiChar已经内部不等于Char
人家Java中用byte, 你应该用AnsiChar, 或byte, 不能用Char, Char现在时16位了,不是8位,所以整个记录比原先的大, 所以后面都出的都是错的。
现在,除非你明确 用ansichar ansiString, string, char 都是双字节宽
----------------------------------------------
-
作者:
男 yugong23 (yugong23) ▲▲▲▲△ -
普通会员
2017/12/12 23:22:20
11楼: 为啥有时用PAnsiChar(@strFile.sFileName)
有时用LongInt(strFile.dwFileSize); ?
@代表取地址,
先搞清楚,怎么访问记录, 怎么访问记录指针
----------------------------------------------
-
作者:
男 yugong23 (yugong23) ▲▲▲▲△ -
普通会员
2017/12/12 23:26:30
12楼: 因为文件名取的多, kbmMemTB_FielPlay.FieldByName('Filename').AsString :=  PAnsiChar(@strFile.sFileName)

 PAnsiChar(@strFile.sFileName)得到的ansiString, 系统会自动转为现在的String,
由于:AsString
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/13 0:15:34
13楼: yongong23:
"人家Java中用byte, 你应该用AnsiChar, 或byte, 不能用Char, Char现在时16位了,不是8位,所以整个记录比原先的大, 所以后面都出的都是错的。"
-- 这个意思是说sFileName的定义不对,导致后面dwFileSize等都取不到正确的数值?有点道理,我试试,谢谢!
关于“为啥有时用PAnsiChar(@strFile.sFileName)
有时用LongInt(strFile.dwFileSize); ?”
,是几种尝试的方法,strFile.dwFileSize,@strFile.dwFileSize,LongInt(@strFile.dwFileSize)都是错误的数值。
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/13 0:19:09
14楼: 官方的MFC定义:
typedef struct 
{
  char sFileName[100];//文件名
  NET_DVR_TIME struStartTime;//文件的开始时间
  NET_DVR_TIME struStopTime;//文件的结束时间
  DWORD dwFileSize;//文件的大小
}NET_DVR_FIND_DATA, *LPNET_DVR_FIND_DATA;
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/13 0:20:02
15楼: 上述delphi、MFC、JAVA的记录定义,都是官方的。
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/13 0:31:16
16楼: yongong23兄,可否使用 packed record?
----------------------------------------------
-
作者:
男 dbyoung (dbyoung) ★☆☆☆☆ -
普通会员
2017/12/13 7:49:43
17楼: LPNET_DVR_FIND_DATA  = ^NET_DVR_FIND_DATA;
PNET_DVR_FIND_DATA   = ^NET_DVR_FIND_DATA;

NET_DVR_TIME = record
    dwYear   : DWORD;          
    dwMonth  : DWORD;          
    dwDay    : DWORD;          
    dwHour   : DWORD;          
    dwMinute : DWORD;          
    dwSecond : DWORD;          
end;

NET_DVR_FIND_DATA = record
  sFileName     : array[0..99] of Ansichar;
  struStartTime : NET_DVR_TIME;
  struStopTime  : NET_DVR_TIME;
  dwFileSize    : DWORD;
end;

无需使用 packed record。
packed 是压缩的意思。
vc 中如果有字节按一字节对齐的申明,才需要 packed。
----------------------------------------------
武汉天气不好
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/12/13 9:38:24
18楼: delphi中:LongInt 就是 Integer 等于 Java 的 Int
======

呵~java又如何?还真没看过几个只学过java没学过c却真懂数据结构的。

dword虽然和int长度一样,都是4字节,但是一个无符号一个有符号都可以划等号么?
----------------------------------------------
--
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/12/13 11:11:35
19楼: 无论什么类型的,大于 2G 的文件,他一定表达不了。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 chro (chro) ★☆☆☆☆ -
普通会员
2017/12/13 21:23:09
20楼: 这个api翻译的,数据类型全错,楼主得补补基本功。数据类型的对应有现成的文档,先找找学习学习;另外建议从c的api翻译,和pascal的数据类型能一一对应
----------------------------------------------
-
作者:
男 yugong23 (yugong23) ▲▲▲▲△ -
普通会员
2017/12/13 22:49:42
21楼: packed record?
最近版本,10.1, 还是10.2, 已经淘汰了。 查官方资料。
可以用sizeof() 测量记录或结构的大小,分别从两种语言里。都有对应的函数。
另外,你怎样的获得的结构内容?
一般c, c++ 翻译的东西, delphi都有类似 xxx(@RecName)来获取,
你使用时, 直接有:recName.fieldname即可, 可以不用记录指针。
这是我过去的经验 , 具体要看实际代码。
有时间看一下,原文:
Migrating Delphi code to Mobile from Desktop;
还有delphi 2009以后,关于unicode的文章,你就明白了
----------------------------------------------
-
作者:
男 yugong23 (yugong23) ▲▲▲▲△ -
普通会员
2017/12/13 22:55:35
22楼: 上述delphi、MFC、JAVA的记录定义,都是官方的。
啥时候的官方?
delphi 2009 开始char 16位
原来8位;

原来内部: AnsiChar=Char, 现在不是了。
现在已不用ansi开头的东西了。除非为了兼容以前的东西
----------------------------------------------
-
作者:
男 somemak (mak) ★☆☆☆☆ -
普通会员
2017/12/18 15:46:47
23楼: yugong23: 这些官方的DEMO,都是海康威视的SDK支持给的,没说啥时候。。。,按你说的思路测试了下,用D7编译,调试的时候,可以查到上述记录结构的值,但是反而播放不了视频了,还没测试PansiChar,但是可以得知解决的思路就是Char。目前是使用XE6,还没用XE10.X

同时谢谢各位的解答!
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行87.89063毫秒 RSS