线程在ReceiveNextEvent中被阻塞 [英] Thread getting blocked in ReceiveNextEvent

查看:63
本文介绍了线程在ReceiveNextEvent中被阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用JNA,我构建了一个api,用于使用Carbon框架从Mac接收操作系统事件. 现在,Carbon.framework中有一个函数定义为:

Using JNA, I have built an api to receive OS events from Mac using Carbon framework. Now, there is a function in Carbon.framework defined as:

OSStatus ReceiveNextEvent (
ItemCount inNumTypes, //ItemCount is a 32-bit iteration count
const EventTypeSpec *inList, //EventTypeSpec is a structure
EventTimeout inTimeout,//EventTimeout is double-length integer of type EventTime
Boolean inPullEvent,
EventRef *outEvent
);

文档说:

inNumTypes

inNumTypes

要等待的事件类型数(如果有任何事件导致该函数返回,则为0). inList.我们正在等待的事件类型列表(如果有任何事件导致该函数返回,则传递NULL).

The number of event types to wait for (0 if any event should cause this function to return). inList. The list of event types we are waiting for (pass NULL if any event should cause this function to return).

inTimeout 返回之前要等待的时间(首选通过kEventDurationForever).  

inTimeout The time to wait before returning (passing kEventDurationForever is preferred).  

inPullEvent 将此参数传递为true,以从队列中删除下一个匹配事件.

inPullEvent Pass true for this parameter to remove the next matching event from the queue.

outEvent 指向与传入列表匹配的下一个事件的指针.如果在inPullEvent参数中传递true,则该事件归您所有,在完成后应释放它.

outEvent A pointer to the next event that matches the list passed in. If you passed true in the inPullEvent parameter, the event is owned by you, and you should release it when done.

返回值 结果指示是否接收到事件,超时已过期或当前事件循环已退出.有关可能的值,请参见"Carbon Event Manager结果代码"(第257页). 讨论

Return Value A result indicating whether an event was received, the timeout expired, or the current event loop was quit. See "Carbon Event Manager Result Codes" (page 257) for possible values. Discussion

此函数尝试获取指定类型的下一个事件.如果事件队列中没有事件匹配,则此函数将运行当前事件循环,直到匹配的事件到达或超时到期为止.除了计时器触发外,在此函数内部时,您的应用程序都被阻止等待事件到来.

This function tries to fetch the next event of a specified type. If no events in the event queue match, this function will run the current event loop until an event that matches arrives, or the timeout expires. Except for timers firing, your application is blocked waiting for events to arrive when inside this function.

同样,我在JNA调用中写了以下内容:

For the same, I have written the below in my JNA call:

NativeLong ReceiveNextEvent(NativeLong inNumTypes, EventTypeSpec[] inList,float inTimeout ,boolean inPullEvent, EdSdkLibrary.__EdsObject outEvent);

__EdsObject扩展了PointerType.

public static class __EdsObject extends PointerType {
    public __EdsObject(Pointer address) {
        super(address);
    }
    public __EdsObject() {
        super();
    }
};

EventTypeSpec is:
public class EventTypeSpec extends Structure {

    public int eventClass;
    public int eventKind;

    protected List getFieldOrder() {
        return Arrays.asList(new String[]{"eventClass", "eventKind"});
    }
}

,呼叫为carbon.ReceiveNextEvent(new NativeLong(1), null, 1.0f, true, eventRef)

上帝知道为什么,但是线程不是从语句中出来的.有趣的是,它确实可以获取事件并进行分派,但不会发出.与我定义函数的方式有关吗?

God knows why, but the thread doesn't come out of the statement. What is interesting, is that it does get events and dispatch them but doesn't come out. Has it got to do with the way I defined the function?

推荐答案

您的映射不正确,并且您没有提供本机代码可以在其中编写事件的事件结构.

Your mapping is incorrect, and you are not providing an event structure into which the native code can write the event.

NativeLong ReceiveNextEvent(NativeLong inNumTypes, EventTypeSpec[] inList, double inTimeout, byte inPullEvent, Pointer outEvent);

必须outEvent中提供一个足够大的缓冲区,以供本机代码写入事件数据(您仅提供未初始化的指针,因此当方法签名实际上正确时会崩溃).

You must provide a buffer in outEvent of sufficient size for the native code to write the event data (you were only providing an uninitialized pointer, thus the crash when your method signature was actually correct).

您没有使用float而不是double参数崩溃的事实仅仅是偶然的.实际发生的是,inTimeout之前的所有参数都被写入了堆栈中的错误位置,因此您的结果将是不确定的.

The fact that you didn't crash with a float rather than double parameter is just happenstance. What actually happens is that all arguments prior to inTimeout get written to the wrong place in the stack, so your results are going to be undefined.

但是,我不明白为什么要查看这些事件的OS事件队列.根据EDSDK文档,事件将发送到直接在EDSDK库中注册的回调.在文档或EDSDK示例代码中,我都没有提到操作系统事件队列.

I don't understand, however, why you're looking at the OS event queue for these events. According to the EDSDK documentation, events are sent to callbacks registered directly with the EDSDK library. I see no mention of the OS event queue in either the docs or the EDSDK sample code.

这篇关于线程在ReceiveNextEvent中被阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆