求一个解决方案.

binbin 2003-01-12 01:24:04
俺在写一个dll的外挂函数库,由另一个软件调用,但在函数处理很大工作量时那个程序就"死"掉了,直到函数返回,界面才能更新.用线程的话,俺的函数返回后那个软件还会有其他工作要做包括多次调用这个函数,会造成同步问题,所以俺希望俺的函数是"阻塞"模式,同时又能使主程序实时处理俺在函数中发出的消息(比如界面的更新)
俺试了:
PeekMessage/DispatchMessage
SendMessage
CallWindowProc
都不行,
俺想实在不行,就做一个独立消息队列,俺的函数被调用时只管向其加入自定义的消息,再由一个线程不断循环出队处理消息,这样可以保证消息是按顺序处理的同时不会阻塞,如处理线程来不及处理则合并或丢弃消息,但不知可不可行,工作量,可能出现的相关技术问题,请指教!
此外,实现这里的队列最好的数据结构/算法是什么.
...全文
9 点赞 收藏 18
写回复
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
binbin 2003-01-15
chinagy(会员GY) :
没用的.这是调用程序消息处理机制本身的问题.一般程序可以用你的方法.
回复
chinagy 2003-01-15
用PostMessage.试试俺的这段代码:

MSG msg;
if ( PeekMessage( &msg,Handle,0,0,PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
回复
qianxh 2003-01-15
如果是BCB做的DLL, 只需在大处理(一般为循环)中定时加
Application->ProcessMessages();
就行了;而如果是单条语句就没办法了,除非该语句有异步模式(如很多数据库的C接口函数).
回复
Behard 2003-01-14
mark
回复
copy_paste 2003-01-12
binbin
你在DLL用了线程?在线程中用消息队列时注意一些问题,你看看:
http://expert.csdn.net/Expert/topic/1327/1327778.xml?temp=.3076441
回复
binbin 2003-01-12
俺只希望在函数中处理有关界面的消息时,调用程序能实时更新.
就象在CB应用程序中用Application->ProcessMessages()那样.
但俺的DLL用C+SDK实现,用了PeekMessage没用.
估计调用程序是在窗口过程中调用俺的函数.

俺是为一个现有的软件(Macromedia Authorware)写DLL函数扩展,不可能协商的.
回复
s98231106 2003-01-12
如果你的DLL调用占用CPU高的话,
估计除了优化你的算法之外,
可能没别的方法了!
回复
googoler 2003-01-12
能不能调用程序的人协商一下调用方法?

如果你的DLL调用占用CPU高的话,估计除了优化你的算法之外,
可能没别的方法了!

-------------------------------------------------------------------
以上所述实属个人胡乱推测,如有雷同,纯属巧合。欢迎各位高手斧正。
仅供参考而已!


回复
binbin 2003-01-12
俺只是做DLL,调用程序不是俺的,所以无法控制这个调用程序在什么时候调用俺的函数.
此外,俺这个DLL是C+SDK实现.
回复
googoler 2003-01-12
用线程的话,俺的函数返回后那个软件还会有其他工作要做包括多次调用这个函数

当线程结术后给你程序发个消息!其它的调用等到消息后才开始调用!

把 线程 的优先级设低一点。(如果你用BCB的TThread,设不了)
或者在线程用一些少量的Sleep(50)等!

队列或栈都可用TList来实现!

不知道能不能帮到你!

-------------------------------------------------------------------
以上所述实属个人胡乱推测,如有雷同,纯属巧合。欢迎各位高手斧正。
仅供参考而已!
回复
copy_paste 2003-01-12
前段写的,可能不是很清楚吧(失败:)

http://expert.csdn.net/Expert/topic/1275/1275761.xml?temp=.5051538
看看这个,可能清楚点。
回复
copy_paste 2003-01-12
PeekMessage和GetMessage为取一个线程消息队列的一个消息,两者不同的区别最重要的在于一个非阻塞(peek)和阻塞(get)。
PeekMessage在取消息时,需要创建一个消息队列来进行才行,一般来说一个Application有一个主线程,它不需要进行创建消息队列

,即说OS为每一个WIN32应用程序分配了一个消息队列。所以在主线程中不需要创建消息队列而能够进行PeekMessage进行取消息,如果是主线

程生成的次/工作线程,则需要通过PeekMessage进行创建消息队列,创建消息队列和取消息不同在于最后标志参数的不同,创建是:

PM_NOREMOVE,取消息则是: PM_REMOVE。线程的PeekMessage只能取本线程的消息。这也是GetMessage和PeekMessage的不同之处,GetMessage

不需要经常PeekMessage进行创建消息而可以进行从消息队列中取出消息来,如果没有消息,则阻塞线程,PeekMessage则不会,有则取出,无

则False返回。

SendMessage和PostMessage区别是同步和异步的区别,还有SendMessage是直接绕过消息队列直接到达消息处理接口,并等待处理完成后才

返回,PostMessage是经过消息队列,由PeekMessage取出,再经消息处理。
回复
binbin 2003-01-12
copy_paste(木石三):
麻烦解释一下PeekMessage的意思,用法及在消息队列中的使用,详细一点好吗?谢谢!
回复
copy_paste 2003-01-12
TCriticalSection *Lock;
TMemoryStream *Stream;

用Lock来同步Stream的操作,
Stream里面保存指令。

AddCommand(...) //将指令用内存的形式保存在Stream中.
PeekCommand(...) //线程将指令取出,并清楚这条指令
ClearCommand(...)//清空

上面的命令函数用Lock进行操作。

DLL线程中创建一个消息队列,有消息时,先处理,没消息时则处理PeekCommand(...);

主线程可以通过PostThreadMessage(再封装一下)来处理是否关闭线程。。。
关于消息队列,应该有的。。。

上面的行不行?呵呵,俺只懂一些VCL。。。
回复
binbin 2003-01-12
俺的思路是:

用户调用初始化函数,建立一个线程,此线程不断循环到队列中取指令并执行,如发现是退出指令则中止循环结束线程.

用户调用相关的函数,向队列中加入指令并立即返回.Authorware可以处理消息

这样,调用函数的效果并不一定立即出现,可能等前面的指令执行完毕才执行.比如等待几分钟以后才执行到,但所有指令是顺序执行的.
用户要中止执行,调用一个函数清空队列.

调用退出函数,向队列中加一个退出指令.
回复
binbin 2003-01-12
为俺自己写;)
现在俺用一个数组循环模拟队列,使用自已定义的消息(俺这里的操作不是普通windows消息),现在...只要一调用俺的初始化函数(由它调用_beginthread)就非法操作!!!

实际上,俺需要的是:Authorware中由用户进行操作,这些操作调用俺的函数.而俺的函数执行需要一个过程,这个过程又对Authorware的界面进行了处理需要其实时响应才能看到效果(否则只能看到结果看不到过程),俺找不到不用多线程使Authorware界面刷新的办法,只能用线程处理而调用函数立即返回使Authorware有机会处理消息,由于用户下达指令速度快于执行速度(比如定义了一个类似宏的指令集),也可能慢于执行速度(用户在等待状态),必须保证指令按下达的顺序执行.
回复
copy_paste 2003-01-12
是自己写还是为客户写的啊。。。
俺不懂这些外挂的东东。。。
回复
googoler 2003-01-12
哇:
为(Macromedia Authorware)写DLL函数扩展!

羡慕ing! 可以拿个?0K还是??0K呀?



回复
发动态
发帖子
Windows SDK/API
创建于2007-08-02

1202

社区成员

C++ Builder Windows SDK/API
申请成为版主
社区公告
暂无公告