关于一个回调函数的问题(200分)

  • 主题发起人 主题发起人 lanruishan
  • 开始时间 开始时间
L

lanruishan

Unregistered / Unconfirmed
GUEST, unregistred user!
DLL是别的公司提供的用VC写的视频捕捉开发包<br>其中有一个函数用来启动数据流回调<br>声明原型为:<br>HRESULT DSStream_GetVideoStream(int iCardID, VideoStreamProc proc, LPVOID pParam)<br>其中参数 VideoStreamProc proc是一个回调函数,声明原型<br>extern &quot;c&quot; void proc (const BYTE* pDIBHead, const BYTE* pDIBits, LPVOID pParam)<br><br>我在delphi中调用如下<br>VideoStreamProc = procedure(const pDIBHead: PByte; const pDIBits: PByte; pParam: PVariant);stdcall;<br><br>function DSStream_GetVideoStream(iCardID: integer; proc: VideoStreamProc; pParam: PVariant): HRESULT; cdecl; external dllname;<br><br>我定义了一个回调函数<br>procedure StreamNotify(const pDIBHead: PByte; const pDIBits: PByte; pParam: PVariant);stdcall;<br>var<br> &nbsp;DIBHead: BitmapInfo;<br> &nbsp;hd: Thandle;<br> &nbsp;jpg: TJpegImage;<br> &nbsp;memStream: TStream;<br> &nbsp;Bitmap: TBitmap;<br>begin<br> &nbsp;if (not assigned(pDIBHead)) or (not Assigned(pDIBits)) then<br> &nbsp; &nbsp;exit;<br> &nbsp;DIBHead := PBitmapInfo(pDIBHead)^;<br><br> &nbsp;Bitmap := TBitmap.Create;<br> &nbsp;Bitmap.Width := DIBHead.bmiHeader.biWidth;<br> &nbsp;Bitmap.Height := DIBHead.bmiHeader.biHeight;<br> &nbsp;hd := DrawDibOpen;<br> &nbsp;DrawDibDraw(hd, Bitmap.canvas.handle, 0, 0, DIBHead.BmiHeader.biwidth, DIBHead.bmiheader.biheight,<br> &nbsp; &nbsp;@DIBHead.bmiHeader, pDIBits, 0, 0, DIBHead.bmiHeader.biWidth, DIBHead.bmiHeader.biheight, 0);<br><br> &nbsp;DrawDibClose(hd);<br>//处理数据<br> &nbsp;memStream := TMemoryStream.Create;<br> &nbsp;jpg := TJpegImage.Create;<br> &nbsp;jpg.Assign(Bitmap);<br> //jpg压缩质量<br> &nbsp;jpg.CompressionQuality := 20; //1<br> &nbsp;jpg.JPEGNeeded; &nbsp; //2<br> &nbsp;jpg.Compress; &nbsp;//3<br> &nbsp;jpg.SaveToStream(memStream); //4<br> &nbsp;SendStream(memStream);//这里处理memStream,如:发送到别的客户端<br> &nbsp;jpg.Free;<br> &nbsp;Bitmap.Free;<br> &nbsp;memStream.Free;<br>end;<br><br>这样回调函数调用后,我不在窗体上移动鼠标没有任何错误,但是我一移动鼠标,程序就出错,错误信息为:“企图释放并非呼叫方所拥有的多用户终端运行程序”<br><br>当我把//1 &nbsp;//2 &nbsp; //3 //4处程序注释掉,错误又没有了<br>请各位高手帮我解决这个问题啊,高分求救!
 
先试试将MOUSE消隐掉结果会如何?
 
To weiliu:<br>你说的将MOUSE消隐掉是什么意思?我的窗体没有定义任何鼠标消息<br>你的意思是截取鼠标消息吗?
 
VideoStreamProc = procedure(const pDIBHead: PByte; const pDIBits: PByte; pParam: PVariant);stdcall; //好像没有stdcall<br><br>另外,pParam: PVariant的定义不对,应该是Pointer
 
To maze:<br>没有stdcall怎么行呢,没有stdcall一调用就会出错<br>另外这里用PVariant和Pointer都一样,反正都是一个指向任意类型的指针<br><br>期待高手们告知正确的解决方法啊!
 
应该不是stdcall,是cdecl
 
用cdecl也不行,发生其它错误
 
是要写视频监视吧?我也遇到过[:D]<br>你把Bitmap: TBitmap;定义为全局的<br>在//1//2//3//4注释后发送消息。在消息处理中写<br><br> jpg.CompressionQuality := 20; //1<br> &nbsp;jpg.JPEGNeeded; &nbsp; //2<br> &nbsp;jpg.Compress; &nbsp;//3<br> &nbsp;jpg.SaveToStream(memStream); //4
 
PVariant和Pointer都一样吗?<br>仔细搞搞清楚吧
 
To 网中戏:<br>&quot;在消息处理中写&quot; 是在什么消息处理中写啊?
 
To maze:<br>虽然PVariant和Pointer有些区别<br>但是在这里用哪个是没有区别的
 
你可以自己定义个消息呀。在回调函数中发消息。<br>收到消息后处理。消息可以列对等待慢慢处理。<br>回调函数中如果来不及处理就完完
 
To 网中戏:<br> &nbsp;按照你的方法,自定义了消息,可是却出现Out Of System Resources错误<br>消息源码如下:<br>procedure TForm1.WMDoBMP(var Msg: TMessage);<br>var<br> &nbsp;tmpJPG: TJpegImage;<br> &nbsp;memStream: TStream;<br>begin<br> &nbsp;tmpJPG := TJpegImage.Create;<br> &nbsp;tmpJPG.Assign(Bitmap);<br> &nbsp;memStream := TMemoryStream.Create;<br> &nbsp;tmpJPG.SaveToStream(memStream);<br> &nbsp;Sendstream(memStream);<br> &nbsp;memStream.Free;<br> &nbsp;tmpJPG.Free;<br>end;
 
Bitmap必须是全局的。转换时锁定
 
To 网中戏:<br> &nbsp;我的Bitmap是全局的啊,转换时怎么锁定<br> &nbsp;还有为什么移动鼠标就发生错误,不移动就不发生错误呢?<br> &nbsp;而且错误就处在jpg的处理上,在这里就出在tmpJPG.SaveToStream(memStream)这一句
 
今天问题终于解决了<br> &nbsp;我在回调函数里把Bitmap直接转换成流,然后把这个流作为一个参数,用另一个函数调用,然后在这个函数里在把流转换成Jpg,问题就没有了<br>procedure StreamNotify(const pDIBHead: PByte; const pDIBits: PByte; pParam: PVariant); stdcall;<br>var<br> &nbsp;DIBHead: TBitmapInfo;<br> &nbsp;hd: Thandle;<br> &nbsp;aBitmap: TBitmap;<br> &nbsp;memStream: TStream;<br>begin<br> &nbsp;if (not assigned(pDIBHead)) or (not Assigned(pDIBits)) then<br> &nbsp; &nbsp;exit;<br> &nbsp;DIBHead := PBitmapInfo(pDIBHead)^;<br><br>// New size of Bitmap<br> &nbsp;aBitmap:=TBitmap.Create;<br> &nbsp;aBitmap.Width := DIBHead.bmiHeader.biWidth;<br> &nbsp;aBitmap.Height := DIBHead.bmiHeader.biHeight;<br> &nbsp;hd := DrawDibOpen;<br> &nbsp;DrawDibDraw(hd, aBitmap.canvas.handle, 0, 0, DIBHead.BmiHeader.biwidth, DIBHead.bmiheader.biheight,<br> &nbsp; &nbsp;@DIBHead.bmiHeader, pDIBits, 0, 0, DIBHead.bmiHeader.biWidth, DIBHead.bmiHeader.biheight, 0);<br> &nbsp;DrawDibClose(hd);<br> &nbsp;memStream:=TMemoryStream.Create;<br> &nbsp;aBitmap.SaveToStream(memStream);<br> &nbsp;Form1.SendStream(memStream);<br> &nbsp;memStream.Free;<br> &nbsp;aBitmap.Free;<br>end;<br><br>procedure TForm1.SendStream(AStream: TStream);<br>var<br> aBitmap: TBitmap;<br> Ajpg:TJpegimage;<br>begin<br> &nbsp;aBitmap:=TBitmap.Create;<br> &nbsp;AStream.Seek(0,soFromBeginning);<br> &nbsp;aBitmap.LoadFromStream(AStream);<br> &nbsp;Ajpg:=TJpegimage.Create;<br> &nbsp;Ajpg.Assign(aBitmap);<br> &nbsp;Ajpg.CompressionQuality:=10;<br> &nbsp;Ajpg.JPEGNeeded;<br> &nbsp;Ajpg.Compress;<br> &nbsp;SendJpg(Ajpg);<br> &nbsp;aBitmap.Free;<br> &nbsp;Ajpg.Free;<br>end;<br><br>为什么要转一到函数调用,问题就解决了呢,而且必须是传出Bitmap的流形式,传出别的都会出错,真是不明白啊
 
现在开始散分了,虽然大家都没有帮我找到正确的答案,但是很感谢大家的热心<br>这里网中戏给我的启发最多,所以我给他110分,其他每人三十分
 
多人接受答案了。
 
后退
顶部