分享
 
 
 

养成好的编码习惯----由一个bug想到的

王朝other·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

最近在做PCM音频合成项目,其中遇到了一个bug,花了大半天才解决,当然修改却很小,是一个很细节的问题。不过回想一下,之前也有类似的经历,觉得有点什么规律,写出来用以自勉,也许各位programmer也曾遇到过吧!:)

下面是部分摘录的代码(颜色visual assist生成的):

/**/

HRESULT CALMInputPin::Convert(IMediaSample *pIn, IMediaSample *pOut)

{

HRESULT hr = S_OK;

/* get suggested size of destination buffer */

long len = pIn->GetActualDataLength();

DWORD suggested_dest_size = 0;

hr = acmStreamSize(m_hStream, len, &suggested_dest_size, ACM_STREAMSIZEF_DESTINATION);

if (hr != MMSYSERR_NOERROR)

return hr;

ACMSTREAMHEADER acmhdr;

acmhdr.cbStruct = sizeof(acmhdr);

hr = pIn->GetPointer(&acmhdr.pbSrc);

hr = pOut->GetPointer(&acmhdr.pbDst);

acmhdr.cbSrcLength = pIn->GetActualDataLength();

acmhdr.cbDstLength = suggested_dest_size;

acmhdr.dwSrcUser = (DWORD)pIn;

acmhdr.dwDstUser = (DWORD)pOut;

acmhdr.dwUser = (DWORD)this;

acmhdr.fdwStatus = 0L;

// ???这里总是返回 error code 10

hr = acmStreamPrepareHeader(m_hStream, &acmhdr, 0);

if (hr != MMSYSERR_NOERROR)

return hr;

/* send buffer to compressor/uncompressor (ACM) */

hr = acmStreamConvert (m_hStream, &acmhdr, ACM_STREAMCONVERTF_BLOCKALIGN);

if (hr != MMSYSERR_NOERROR )

{

return hr;

}

hr = acmStreamUnprepareHeader(m_hStream, &acmhdr, 0);

if (hr != MMSYSERR_NOERROR)

return hr;

REFERENCE_TIME rtStart, rtEnd;

len = pIn->GetActualDataLength();

pIn->GetTime(&rtStart, &rtEnd);

rtEnd = rtStart + len;

pOut->SetTime(&rtStart, &rtEnd);

pOut->SetActualDataLength(acmhdr.cbDstLength);

return S_OK;

}

//

这里涉及到DirectShow和ACM的结构和函数,不过思路还比较清晰。细心的话可以看出这些代码,是“拼凑”出来的(提高开发速度嘛!),分别来自是网上的开源项目和DirectShow附带的源文件。从逻辑上说也没有什么问题,当然调试发现总是有一个错误。

唯一的线索是error code 10,Error Lookup解释为“环境错误”,这能说明什么问题呢?当然笔者对ACM也不是很了解,于是花了几个小时看了文档,了解了一些背景知识,但没有什么发现什么有价值的东西。又参考了其它项目的代码,不过别人使用的c++模板语法,而且要拆解出关键的代码需要很多时间,所以搞来搞去也没有思路。

思路在哪里?在经过了一些其它的尝试的时候,觉得还是不行。最后又去调试别人的代码,可以运行通过。有一点是可以肯定的,程序的流程没有问题,可能是其中遗漏了某些细节。对比两段代码后发现,ACMSTREAMHEADER的某些成员变量没有初始化。难道真是这个问题吗?于是在结构体变量申明后面添加了

memset (&acmhdr, 0, sizeof(acmhdr));

这样所有的成员先初始化为0。在调试,问题解决了!后来在MSDN里面发现了ACMAPP Sample工程,里面有这么一段代码:

pash->cbStruct = sizeof(*pash);

pash->fdwStatus = 0L;

pash->dwUser = 0L;

pash->pbSrc = paacd->pbSrc;

pash->cbSrcLength = paacd->cbSrcReadSize;

pash->cbSrcLengthUsed = 0L;

pash->dwSrcUser = paacd->cbSrcReadSize;

pash->pbDst = paacd->pbDst;

pash->cbDstLength = paacd->cbDstBufSize;

pash->cbDstLengthUsed = 0L;

pash->dwDstUser = paacd->cbDstBufSize;

这个结构体的定义如下:

typedef struct tACMSTREAMHEADER

{

DWORD cbStruct; // sizeof(ACMSTREAMHEADER)

DWORD fdwStatus; // ACMSTREAMHEADER_STATUSF_*

DWORD dwUser; // user instance data for hdr

LPBYTE pbSrc;

DWORD cbSrcLength;

DWORD cbSrcLengthUsed;

DWORD dwSrcUser; // user instance data for src

LPBYTE pbDst;

DWORD cbDstLength;

DWORD cbDstLengthUsed;

DWORD dwDstUser; // user instance data for dst

DWORD dwReservedDriver[10]; // driver reserved work space

} ACMSTREAMHEADER, *PACMSTREAMHEADER, FAR *LPACMSTREAMHEADER;

11个成员虽然没有全部清零,但是除了dwReservedDriver[10]都赋了值。

总结:这类错误是由于某些结构体成员没有正确的赋值而造成的,在Debug模式中没有赋值的变量一般初始化为0xcc,在Release模式中一般是0x00,都是按字节序。所以编译器为了做了赋值,但是这些值是错误的,所以在编码的过程中必须处理这个细节。要么先全部初始化为0,要么对所有相关的变量都赋值。

笔者写程序也有3年了,但是仍然犯这个错误,虽然是在追的比较急的时候。所以必须在平时养成良好的习惯,同时克服外部的压力,写出高质量的代码;而不是风风火火赶代码,最后还得花很多时间去找错,得不偿失!这就是笔者要与大家共勉的啊!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有