使用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)
上帝知道为什么,但这句话并没有脱离声明。有趣的是,它确实得到了事件并发送它们但却没有出来。它与我定义函数的方式有关吗?
答案 0 :(得分:1)
您的映射不正确,并且您没有提供本机代码可以在其中编写事件的事件结构。
NativeLong ReceiveNextEvent(NativeLong inNumTypes, EventTypeSpec[] inList, double inTimeout, byte inPullEvent, Pointer outEvent);
你必须提供足够大小的outEvent
缓冲区,以便本机代码写入事件数据(你只提供了一个未初始化的指针,因此当你的方法签名是崩溃时崩溃实际上是正确的。)
您没有使用float
而不是double
参数崩溃的事实只是偶然事件。实际发生的是inTimeout
之前的所有参数都被写入堆栈中的错误位置,因此结果将是未定义的。
但是,我不明白为什么要查看这些事件的OS事件队列。根据EDSDK文档,事件被发送到直接向EDSDK库注册的回调。我没有在docs或EDSDK示例代码中提到OS事件队列。