对此非常好奇,从我自己的经验来看,所有的图形编程似乎都与C或C++有关.像Direct10X一样.函数式编程语言是否提供某种图形库来开发视频游戏?
考虑以下程序:
#include <iostream>
#include <cmath>
#include <cstring>
#include <xmmintrin.h>
using namespace std;
int main()
{
// 4 float32s.
__m128 nans;
// Set them all to 0xffffffff which should be NaN.
memset(&nans, 0xff, 4*4);
// cmpord should return a mask of 0xffffffff for any non-NaNs, and 0x00000000 for NaNs.
__m128 mask = _mm_cmpord_ps(nans, nans);
// AND the mask with nans to zero any of the nans. The result should be 0x00000000 for every component.
__m128 z = _mm_and_ps(mask, nans);
cout << …
Run Code Online (Sandbox Code Playgroud) 如何将 PCI 基地址寄存器 (BAR) 从 PCIDriverKit 驱动程序 (DEXT) 内存映射到用户空间应用程序?
从驱动程序扩展到应用程序的内存映射可以通过在用户客户端子类(在驱动程序端)中实现IOUserClient::CopyClientMemoryForType然后调用IOConnectMapMemory64(从用户空间应用程序端)来完成。这在相关的答案中已经得到了非常好的和彻底的解释。
唯一缺少的一点是获取与所需 PCI BAR 相对应的IOMemoryDescriptor,以便从CopyClientMemoryForType
实现中返回它。
另一种方式问,给定以下简化代码,会执行什么imaginaryFunctionWhichReturnsTheBARBuffer
?
kern_return_t IMPL(MyUserClient, CopyClientMemoryForType) //(uint64_t type, uint64_t *options, IOMemoryDescriptor **memory)
{
IOMemoryDescriptor* buffer = nullptr;
imaginaryFunctionWhichReturnsTheBARBuffer(ivars->pciDevice /* IOPCIDevice */, kPCIMemoryRangeBAR0, &buffer);
*memory = buffer;
return kIOReturnSuccess;
}
Run Code Online (Sandbox Code Playgroud)
前面的代码ivars->pciDevice
中指的是一个现成的IOPCIDevice(例如:它已经根据最新的最佳实践成功匹配、打开和配置)。
这意味着已经可以使用各种配置和内存读/写方法来访问所需 PCI BAR 内存的显式偏移量。缺少(或不清楚)的是如何使用这些 API(或等效 API)将与 PCI BAR 对应的整个缓冲区映射到用户空间应用程序。
我需要为系统音频捕获(基于 Soundflower)开发音频设备驱动程序。
但很快就出现了一个问题,似乎 IOAudioFamily 堆栈在 OSX 10.10 及更高版本中已被弃用。
查看IOAudioDevice
和IOAudioEngine
头文件,似乎苹果现在建议使用<CoreAudio/AudioServerPlugIn.h>
在用户空间中运行的API。但是我找不到有关此用户空间设备驱动程序主题的大量信息。似乎唯一的资源是 Apple 提供的来自https://developer.apple.com/library/prerelease/content/samplecode/AudioDriverExamples/Introduction/Intro.html 的示例设备
查看示例我发现它更难开发用户空间驱动程序而不是基于 I/O Kit 内核的更多工作。
那么问题来了,在用户空间而不是内核空间开发设备驱动程序的动机是什么?
当应用程序进程启动XPC帮助程序进程时,它实际上并不以经典的UNIX样式执行fork()/ exec()本身.相反,它向launchd发送一条消息,它为它做了肮脏的工作.因此,如果您在XPC进程上查询父进程,它将作为launchd进程返回.
但是,如果在分层流程视图中打开活动监视器,则XPC帮助程序进程将显示在请求它们的原始应用程序下方,例如:
在我正在研究的软件中,了解这些过程之间的关系将非常有用.到目前为止,我们一直在使用常规的BSD父进程信息,但随着一切都向XPC发展,这已经不再使用了.
所以:
有一个kext涉及,所以我很乐意在内核而不是用户空间中直接提取这些信息,但我似乎无法弄清楚它存储在哪里.
更新:关于Apple的darwin-kernel邮件列表的讨论:http://lists.apple.com/archives/darwin-kernel/2015/Mar/msg00001.html
在某些应用程序中,应用程序直接处理键盘快捷键是有意义的,否则键盘快捷键将绑定到系统范围的组合.例如,⌘-Space(通常是Spotlight)或⌘-Tab(通常是app切换器).这适用于各种Mac应用程序,例如VMWare Fusion,Apple自己的屏幕共享和远程桌面客户端(分别将事件转发到VM或服务器,而不是在本地处理它们),以及应用程序中的一些类似的第三方应用程序商店.
我们希望在我们正在开发的应用程序中实现这样的模式,但是很难确定如何做到这一点.我应该指出,有问题的应用程序是一个常规的前台应用程序,是沙箱,任何解决方案都必须符合App Store规则.商店中的其他应用程序可以执行此操作的事实意味着这必须是可能的.
要清楚,我们希望:
Apple的Event Architecture文档表明前台应用程序应该已经接收了这些事件.(这大约只有同期水平搬运东西,如电力会谈和弹出按钮,这是很好的.)它继续提出,而关键事件文件还暗示说NSApplication
的sendEvent:
方法就是检测基于修正标志潜在的快捷方式,调度他们到窗口,如果失败,到菜单栏.它没有明确说明全局绑定快捷方式会发生什么.
我尝试了子类化NSApplication
和重写sendEvent:
.无论我是否将所有事件都传递给超类实现,或者如果我说,过滤修饰键事件,当我按⌘-Space时,我会收到按下并释放命令(⌘)键的事件,但不会显示空格键.Spotlight UI总是会弹出.
我没有从Apple或其他方面找到有关子类化NSApplication及其早期事件处理的更多信息.我似乎无法找出检测和处理全局快捷方式的级别.
有人可以指点我正确的方向吗?
可行的解决方案不起作用:
建议我在其他Stack Overflow帖子中看到但不适用于我见过的其他应用程序(这会破坏App Store规则):
这两个会矫枉过正,无论如何,因为他们让你拦截所有的活动在所有时候,不只是当你的应用程序是前台应用程序.
NSevent
的addGlobalMonitorForEventsMatchingMask:handler:
同时并不妨碍全球快捷方式处理从发射这些事件,所以甚至没有尝试它.
我的Cocoa应用程序需要运行一堆命令行程序.其中大多数都是非交互式的,所以我用一些命令行参数启动它们,它们做它们的事情,输出一些东西然后退出.其中一个程序是交互式的,所以它输出一些文本和stdout的提示,然后期望stdin上的输入,这一直持续到你发送一个退出命令.
非交互式程序只是将大量数据转储到stdout然后终止,这些程序相对简单:
NSPipe
为stdout/stdin/stderr 创建sNSTask
用这些管子发射然后,要么
NSFileHandle
管道的另一端以读取所有数据,直到流结束并在任务结束时一次性处理它要么
-fileDescriptor
从NSFileHandle
输出管道的另一端获取s .dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, ...
read()
read()
报告0字节读取)这两种方法都完全打破了交互式工具.显然我不能等到程序退出,因为它位于命令提示符下,除非我告诉它,否则永远不会退出.另一方面,NSPipe
缓冲数据,因此您以缓冲区大小的块接收它,除非CLI程序恰好刷新管道,在我的情况下不会.初始命令提示符比缓冲区大小小得多,所以我没有收到任何东西,它只是坐在那里.所以NSPipe
也是一个禁忌.
经过一些研究,我确定我需要使用伪终端(pty)代替NSPipe.不幸的是,我一无所获,只能让它运转起来.
而不是stdout管道,我创建一个像这样的pty:
struct termios termp;
bzero(&termp, sizeof(termp));
int res = openpty(&masterFD, &slaveFD, NULL, &termp, NULL);
Run Code Online (Sandbox Code Playgroud)
这给了我两个文件描述符; 我把它slaveFD
交给了一个NSFileHandle
,它被传递给了NSTask
stdout或stdout和stdin.然后我尝试从主方进行通常的异步读取.
如果我运行我在终端窗口中控制的程序,它会通过输出2行文本开始,一行18字节长,包括换行符,一个22字节,并且没有命令提示符的换行符.在那40个字节之后,它等待输入.
如果我只是将pty用于stdout,我会从受控程序中收到18个字节的输出(恰好是一行,以换行符结尾),而不是更多.在最初的18个字节后,所有东西都只是位于那里,没有更多的事件 - GCD事件源的处理程序不会被调用.
如果我也将pty用于stdin,我通常会收到19个字节的输出(前面提到的行加上下一行的一个字符),然后受控程序立即死掉.如果我在尝试读取数据之前稍等一下(或者调度噪声导致一个小的暂停),我实际上会在程序再次立即死亡之前得到整个40个字节.
有一次我想知道我的异步读取代码是否有缺陷,所以我用NSFileHandle
s及其-readInBackgroundAndNotify
方法重新做了一切.这与使用GCD时的行为相同.(我最初在NSFileHandle
API上选择了GCD,因为似乎没有任何异步写入支持NSFileHandle
)
经过一天徒劳无功的尝试到达这一点,我可以做一些帮助.我正在尝试做什么有一些基本问题吗?为什么将stdin连接到pty终止程序?我没有关闭pty的主端,所以它不应该接收EOF.抛开stdin,为什么我只得到一行的产出?我在pty的文件描述符上执行I/O的方式有问题吗?我是否正确使用主站和从站结束 - …
根据我阅读的文档和xnu源代码,我了解到Mac OS X 使用统一缓冲区缓存(UBC)缓存文件 I/O. UBC根据可用的RAM增长尽可能大,但UBC页面是内存越来越紧张时首先被牺牲的页面.
在我的驱动程序中,我处理各种磁盘元数据.我希望能够使用UBC或类似的机制来保持MRU缓存这些数据以加快速度,同时让内核能够在需要时收回内存.然而,元数据不代表文件数据,因此不直接落入UBC的域.是否有我可以使用的低级机制,或者我可以以某种方式仅使用UBC中处理缓冲区本身的部分?
我目前正在寻找HFS +源代码,试图弄清楚它是否以及如何缓存文件系统元数据,尽管没有太大的成功.
主要的替代方案当然是为缓存保留特定的内存区域并进行自己的LRU剔除.我可以选择一个固定的缓存大小或者使用某种启发式方法,但是当RAM丰富时它总是会占用太少的内存,而当它没有时它会占用太多的内存.
更新:
在搜索了一些之后,我发现IOBufferMemoryDescriptor
可以使用该kIOMemoryPurgeable
选项创建实例.这允许你调用IOMemoryDescriptor::setPurgeable()
它来标记内存"公平游戏"以便丢弃.我会尝试并用结果更新问题.
我正在尝试对Mac上的磁盘分区表进行微妙的修改; 特别是,我需要更改分区的类型.diskutil
不支持这个,所以我不能使用它.gpt
如果磁盘未使用,它可以正常工作(例如,通过修改的命令行实用程序).如果是,则在打开设备文件时失败:
int fd = open("/dev/disk1", O_RDWR);
Run Code Online (Sandbox Code Playgroud)
fd
为-1并errno
指示错误"资源忙".
我意识到我可以从不同的驱动器重启机器,从那里修改原始磁盘,然后重新启动.但是,从我的应用程序内部实现自动化/可靠性并不容易.此外,diskutil
编辑实时设备的分区表没有问题,也没有bootcamp安装程序.
有没有一种已知的方法来做到这一点?最糟糕的情况是,我可以尝试在内核中执行此操作,但是kexts并非真正用于执行一次性操作,而我需要做的事情在用户空间中非常简单,但在内核中却相当困难.
有任何想法吗?
注意:我正在运行所有内容sudo
,因此它不应该是权限问题.
我想知道open(2)
bash 脚本中进行了哪些调用。
我编写了以下拦截系统调用的程序:
#include <fcntl.h>
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#define DYLD_INTERPOSE(_replacment,_replacee) \
__attribute__((used)) static struct{ const void* replacment; const void* replacee; } _interpose_##_replacee \
__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacment, (const void*)(unsigned long)&_replacee };
static
int
my_open(const char *filename, int oflag, mode_t mode)
{
printf("$jason$ open: %s\n", filename);
return open(filename, oflag, mode);
}
DYLD_INTERPOSE(my_open, open)
Run Code Online (Sandbox Code Playgroud)
然后我使用以下命令运行:
clang -dynamiclib libfile.c -o libfile.dylib
export DYLD_INSERT_LIBRARIES=libfile.dylib
touch /tmp/testingtesting
Run Code Online (Sandbox Code Playgroud)
这不起作用。
我用自己编译的程序尝试了一下,效果很好。我用brew编译的程序尝试了一下,效果很好。我阅读了touch.c的源代码。它调用open(2)
.
然后我禁用了 …