1, 缘起

某次开发语音对讲windows程序,采用delphi语言,及delphix的TDXSound控件。

DXSound提供了TSoundCaptureStream类,可以实现指定频率、位数、声道的声卡录音。在其OnFilledBuffer事件处理中,将音频数据发给指定设备就能实现流式对讲。

先写了一个测试EXE程序,运行OK。然后需要将其功能封装为DLL函数,供其它应用程序开发时调用,封装完毕,结果发现麦克风的声音发送不出去。WTF?

2,分析

debug发现,调用DLL开始对讲函数后,OnFilledBuffer中的回调事件代码一直未被执行。这在exe程序中是不存在的。记得uDPServer控件有类似的毛病,如果不设置为其ThreadedEvent属性为True,那么在DLL中其ONUDPRead事件基本上也是收不到任何信息。

但DXSound中有类似的属性设置吗?查看DXSounds单元的源码,发现TSoundCaptureStream有一个FNotifyThread属性(又是线程!),当调用start方法开始捕捉声卡时,会创建一个TSoundCaptureStreamNotify通知线程,而这个通知线程调用了Synchronize(Update)方法向主线程发送捕捉到了声卡信息。

查询资料发现,若工程文件是DLL而不是EXE的话,Application默认不创建窗口句柄,因此Synchronize 向Application发送消息根本无法响应。

参见:https://www.cnblogs.com/enli/archive/2010/09/28/1837728.html

3,解决

解决方案也是采用了上文中提供的方法,在DLL的l工程文件中加入以下语句 ,问题解决。

Application.Initialize;

if Application.Handle =  then
begin
Application.CreateHandle;
end; Application.Run;

DLL线程中坑爹的Synchronize?的更多相关文章

  1. [delphi]在DLL中多线程同步Synchronize卡死问题

    在dll中多线程同步调用Synchronize不可以,会出现假死卡住的现象.可通过Sendmessage实现. 转网上其他文章解释: Application.Initialize; begin     ...

  2. 【转载】Delphi7从子线程中发送消息到主线程触发事件执行

    在对数据库的操作时,有时要用一个子线程来进行后台的数据操作.比如说数据备份,转档什么的.在主窗口还能同是进行其它操作.而有时后台每处理一个数据文件,要向主窗口发送消息,让主窗口实时显示处理进度在窗口上 ...

  3. DLL函数中内存分配及释放的问题

    DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了.主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的 情况,这里总结一下,做为资料. 错误 ...

  4. TMsgThread, TCommThread -- 在delphi线程中实现消息循环

    http://delphi.cjcsoft.net//viewthread.php?tid=635 在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使 ...

  5. TMsgThread, TCommThread -- 在delphi线程中实现消息循环(105篇博客,好多研究消息的文章)

    在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供.   花了两天的事件研究了 ...

  6. 为什么JAVA线程中没有Running状态?

    面试官问:为什么 Java 线程没有 Running 状态?我懵了 —— 转  芋道源码 什么是 RUNNABLE? 与传统的ready状态的区别 与传统的running状态的区别 当I/O阻塞时 如 ...

  7. 在非UI线程中自制Dispatcher

    在C#中,Task.Run当然是一个很好的启动新并行任务的机制,但是因为使用这个方法时,每次新的任务都会在一个新的线程中(其实就是线程池中的线程)运行 这样会造成某些情形下现场调度的相对困难,即使我隔 ...

  8. 线程中调用python win32com

    在python的线程中,调用win32com.client.Dispatch 调用windows下基于COM组件的应用接口, 需要在调用win32com.client.Dispatch前,调用pyth ...

  9. 为什么说invalidate()不能直接在线程中调用

      1.为什么说invalidate()不能直接在线程中调用?2.它是怎么违背单线程的?3.Android ui为什么说不是线程安全的?4.android ui操作为什么一定要在UI线程中执行? 1. ...

随机推荐

  1. 【bzoj2809】[Apio2012]dispatching (左偏树)

    我们需要枚举根,然后从其子树内选尽量多的点,薪水不超过M,可是暴力复杂度不对.于是考虑自下而上合并树(开始每棵树内只有一个节点,就是自己) 每个树是一个堆,我们维护树的节点个数和薪水总和,合并时,不断 ...

  2. C#生成Excel文件后彻底解除占用代码(来着CSDN)

    http://bbs.csdn.net/topics/280078428 jy251 LS说KILL进程的朋友们···我说...你们真行!!!如果用户是administrator还行,如果不是怎么办? ...

  3. 基于Servlet API 如何实现转向时不再地址栏中显示转向后的地址?

    A:redirect() B:sendRedirect()  C:forward()  D:transform()

  4. C项目实践--图书管理系统(1)

    1.功能需求分析 图书管理系统主要用于对大量的图书信息,包括书名.作者.出版社.出版日期.ISBN(书号)等进行增.删.改.查以及保存等操作.同时也包括对用户的管理,用户包括管理员和普通用户两种权限, ...

  5. Koa2学习(六)使用koa-router

    Koa2学习(六)使用koa-router 配置简单路由 引入中间件 配置需要的路由 通过app.use注册路由 const Koa = require('koa') const app = new ...

  6. maximize_window fullscreen_window minimize_window

    # Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreemen ...

  7. VS2010调用外部webservice

    vs2010怎么调用web服务webservice方法,以vs2010为例.Vs的各个版本的此项功能操作基本一致. 工具/原料 vs2010 在“服务引用设置”对话框中,单击“添加 Web 引用”. ...

  8. 【CJOJ】Contest4 - A+B Series

    Position:http://oj.changjun.com.cn/contest.php?cid=4 A经典题目 // <A.cpp> - Sun Oct 9 15:28:01 201 ...

  9. springmvc处理ajax跨域

    解决跨域问题:在web.xml中配置corsFilter mvc.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!- ...

  10. python的md5和base64加密

    在用jmeter测试接口时,有的请求参数会加密,例如,回流接口:http://ip:port/oms-gateway-datareflow-mq/orderReflow/tmsPracticeActi ...