线程在ReceiveNextEvent中被阻止

时间:2013-04-02 08:59:39

标签: java jna

使用JNA,我构建了一个api,使用Carbon框架从Mac接收OS事件。 现在,Carbon.framework中的函数定义为:

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

     

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

     

inTimeout   返回之前等待的时间(首选传递kEventDurationForever)。       

     

inPullEvent   对此参数传递true以从队列中删除下一个匹配事件。

     

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

     

返回值   指示是否已收到事件,超时到期或当前事件循环的结果已退出。有关可能的值,请参阅“碳事件管理器结果代码”(第251页)。   讨论

     

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

同样,我在JNA电话中写了以下内容:

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)

上帝知道为什么,但这句话并没有脱离声明。有趣的是,它确实得到了事件并发送它们但却没有出来。它与我定义函数的方式有关吗?

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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