我有一个已经存在了一段时间(超过10年)的C ++代码库,并且可以正常运行,但是我注意到当我在OS / X 10.8.x(Mountain Lion)下对其进行编译时,编译器会发出关于以下内容的弃用警告:它调用的一些Carbon函数:
../system/SetupSystem.cpp:575:44: warning: 'UpTime' is deprecated: first
deprecated in OS X 10.8 [-Wdeprecated-declarations]
../system/SetupSystem.cpp:575:22: warning: 'AbsoluteToNanoseconds' is
deprecated: first deprecated in OS X 10.8 [-Wdeprecated-declarations]
../system/SystemInfo.cpp:249:25: warning: 'MPProcessors' is deprecated: first deprecated in OS X 10.7 [-Wdeprecated-declarations]
Run Code Online (Sandbox Code Playgroud)
我想将此代码库升级到Apple认可的新工作方式(从而避免警告和将来(如果Apple最终删除这些功能时)的麻烦),但是我不知道新标准是什么。我浏览了developer.apple.com上的OS / X文档,但是缺少搜索技能或者缺少他们的文档,因为我发现这些功能几乎没有,也没有替代品。
我有一些具体问题:
我有一个Qt应用程序(出于超出此问题范围的原因)将每个窗口作为一个单独的进程启动.
这样可以正常工作,但在MacOS/X下,每个窗口/进程都显示为Dock中的单独条目.因此,当用户打开十几个窗口时,码头上有十几个相同的图标,这不是很有用(因为很难分辨哪个是哪个,图标开始变小).
有没有办法告诉Dock在单个Dock图标下将所有这些进程组合在一起?(特定于Mac的API会很好)
我已经在我的Qt应用程序的Windows版本中添加了一个迷你核心转储功能(通过__try/__ except和MiniDumpWriteDump()),这样如果/当我的应用程序崩溃时,.dmp文件将被写入磁盘让我以后查看和调试.
这非常有效,但是对于测试,我希望有一个已知可靠的方法来使我的程序崩溃.例如,GUI中可能存在"立即崩溃"按钮,当用户单击它时,它将导致应用程序故意崩溃.
当然,一种方法是这样的:
int * badPointer = NULL;
*badPointer = 666;
Run Code Online (Sandbox Code Playgroud)
这对我有用,但我不喜欢这种方法,因为它依赖于未定义的行为 - 特别是,C++标准不要求上面的代码导致崩溃,所以它是可能的(从语言 - 律师的角度来看) )当上面的代码执行时,编译器的某些未来版本不会崩溃.
作为一种更"官方"的方法,我试过这个:
abort();
Run Code Online (Sandbox Code Playgroud)
...它会终止程序,但它不会导致Windows结构化异常触发MiniCrashDump处理程序,因此不会写入.dmp文件.
我的问题是,是否有一个"官方正确的方式"来破坏我的计划?我看到Windows API有一个我可以调用的RaiseException()函数,但我不确定它应该是什么正确的参数.这是要走的路,还是有一些更具体的电话,我会更好用?
我创建了一个私有API,它假定类中第一个成员对象的地址与类的this-pointer相同......这样,成员对象可以简单地派生出一个指向它的对象的指针.成员,无需显式存储指针.
鉴于我愿意确保容器类不会从任何超类继承,不会有任何虚方法,并且执行此技巧的成员对象将是第一个声明的成员对象,那个假设会保留对任何C++编译器有效,还是需要使用offsetof()运算符(或类似)来保证正确性?
换句话说,下面的代码完成了我在g ++下的期望,但它能在各处工作吗?
class MyContainer
{
public:
MyContainer() {}
~MyContainer() {} // non-virtual dtor
private:
class MyContained
{
public:
MyContained() {}
~MyContained() {}
// Given that the only place Contained objects are declared is m_contained
// (below), will this work as expected on any C++ compiler?
MyContainer * GetPointerToMyContainer()
{
return reinterpret_cast<MyContainer *>(this);
}
};
MyContained m_contained; // MUST BE FIRST MEMBER ITEM DECLARED IN MyContainer
int m_foo; // other member items may be declared after m_contained
float m_bar; …Run Code Online (Sandbox Code Playgroud) 当我在Mac上运行下面的程序(OS/X 10.6.4)时,我得到以下输出:
$ ./a.out
Read 66 lines of output from /bin/ps
Read 0 lines of output from /bin/ps
Read 0 lines of output from /bin/ps
Read 0 lines of output from /bin/ps
Read 0 lines of output from /bin/ps
Run Code Online (Sandbox Code Playgroud)
为什么popen()只在我第一次调用它时读取数据,后续传递没有返回输出?
#include <stdio.h>
int main(int argc, char ** argv)
{
int i;
for (i=0; i<5; i++)
{
FILE * psAux = popen("/bin/ps ax", "r");
if (psAux)
{
char buf[1024];
int c = 0;
while(fgets(buf, sizeof(buf), psAux)) c++;
printf("Read %i lines of …Run Code Online (Sandbox Code Playgroud) 这是一个Python风格的问题 - 我的Python代码有效,我只是在寻找一种编码约定的建议,这将使代码更容易阅读/理解/调试.
具体来说,我正在开发一个Python类,它允许调用者将小部件添加到自定义GUI.为了设置GUI,用户将编写一个方法,将小部件(命名或匿名)添加到小部件区域,以便小部件形成树(在GUI中很常见).
为了允许用户设置窗口小部件树而不必为每个容器窗口小部件命名(然后在每次添加子窗口小部件时显式引用该父窗口小部件),我的API支持"父窗口小部件"的概念堆".在声明容器窗口小部件时,用户可以指定将该窗口小部件推送到此堆栈,然后默认情况下,任何其他窗口小部件(未明确指定父窗口)将添加到堆栈顶部的父窗口.这是我的意思的一个简单例子:
def SetupGUI(self):
self.AddWidget(name="root", type="container", push=True)
self.AddWidget(type="container", push=True)
for i in range(0,8):
self.AddWidget(name="button%i"%i, type="button")
self.PopParentWidget() # pop the buttons-container off the parents-stack
self.AddWidget(type="container", push=True)
for i in range(0,8):
self.AddWidget(name="slider%i"%i, type="slider")
self.PopParentWidget() # pop the sliders-container off the parents-stack
self.PopParentWidget() # pop the container "root" off the parents-stack
Run Code Online (Sandbox Code Playgroud)
这很方便,但我发现当GUI层次结构变得更复杂时,开始变得难以分辨哪个对self.PopParentWidget()的调用对应于哪个容器小部件.很容易放入太多,或者太少,并最终在GUI中产生非常有趣但无意的结果.
所以我的问题是,没有强迫PopParentWidget()采用一个显式的小部件名称(我想避免,因为我不想命名每个容器小部件),有什么我可以做的推动/代码中的pop配对对眼睛更明显?
在C/C++中,我会使用缩进来做,但是使用Python我不允许这样做.例如,我希望能够做到这一点:
def SetupGUI(self):
self.AddWidget(name="root", type="container", push=True)
self.AddWidget(type="container", push=True)
for i in range(0,8):
self.AddWidget(name="button%i"%i, type="button")
self.PopParentWidget() # pop the buttons-container off the parents-stack
self.AddWidget(type="container", push=True)
for i in …Run Code Online (Sandbox Code Playgroud) 首先,一些背景信息:我正在编写一个 MacOS/X 应用程序,它使用 CoreAudio 从 CoreAudio 设备的输入流接收音频信号,对音频进行一些实时处理,然后将其发送回该 CoreAudio 设备的输出流供用户收听。
此应用程序使用较低级别的 CoreAudio API(即AudioDeviceAddIOProc、AudioDeviceStart等,而不是 AudioUnit)来获取对用户指定的 CoreAudio 设备的独占访问权限,将其设置为所需的采样率 (96kHz),然后执行其操作。它运行得很好,我对其性能非常满意。
然而,我的程序目前有一个限制——它一次只能使用一个 CoreAudio 设备。我想要做的是扩展我的应用程序,以便用户可以彼此独立地选择他的“输入 CoreAudio 设备”和“输出 CoreAudio 设备”,而不是仅限于使用一个同时提供两个功能的 CoreAudio 设备。输入音频源和输出音频接收器。
我的问题是,推荐的技术是什么?我可以要求两个 CoreAudio 设备设置为相同的采样率,但即使我这样做了,我想我也必须处理各种问题,例如:
集成AudioDeviceStart()来自两个设备的单独启动的回调,我怀疑这些回调不会以任何明确定义的顺序调用,甚至可能会彼此同时调用(?)。我需要以某种方式将音频从一个回调传递到另一个回调,理想情况下不会显着增加音频延迟。
处理两个设备采样时钟速率的差异。例如,即使两个设备名义上都设置为 96kHz 采样率,我怀疑实际上可能是这样的情况,例如上游设备以 95.99999kHz 生成样本,而下游设备以 96.000001kHz 消耗样本(反之亦然),并且这最终会导致我在给定的渲染回调期间得到“不够”或“太多”的样本来供给下游设备,从而导致故障。
我还没有考虑过的其他问题
其他 MacOS/X 程序如何处理这些问题?
我有一个基于 ARM 的无头 Linux (v3.10.53-1.1.1) 系统,没有启用交换空间,我偶尔会看到进程被 OOM 杀手杀死,即使有足够的 RAM 可用。
定期运行echo 1 > /proc/sys/vm/compact_memory似乎可以阻止 OOM 杀手,这让我认为内存碎片是罪魁祸首,但我不明白为什么用户进程无论如何都需要物理上连续的块;据我了解,即使在最坏的情况下(完全碎片,只有单独的 4K 块可用),内核也可以简单地分配必要数量的单独 4K 块,然后使用虚拟内存的魔力(tm)来制作它们看起来与用户进程连续。
有人可以解释为什么 OOM-killer 会被调用来响应内存碎片吗?这只是一个有缺陷的内核还是有真正的原因?(即使内核确实需要对内存进行碎片整理以满足请求,它难道不应该自动执行此操作而不是放弃并 OOM 吗?)
我在下面粘贴了一个 OOM-killer 调用示例,以防它对事情有任何启发。我可以随意重现故障;这个调用是在计算机仍然有大约 120MB 可用 RAM(根据free)时发生的,以响应我的测试程序分配内存,一次分配 10000 个 400 字节。
May 28 18:51:34 g2 user.warn kernel: [ 4228.307769] cored invoked oom-killer: gfp_mask=0x2084d0, order=0, oom_score_adj=0
May 28 18:51:35 g2 user.warn kernel: [ 4228.315295] CPU: 2 PID: 19687 Comm: cored Tainted: G O 3.10.53-1.1.1_ga+gf57416a #1
May 28 18:51:35 g2 user.warn kernel: [ 4228.323843] …Run Code Online (Sandbox Code Playgroud) 几个星期前,我开始在我的SVN存储库的主干中进行更改,我认为这将是相当小的.
经过几个小时的工作,我意识到这个变化比我想象的更重要,我觉得立刻检查我的变化是太危险了,所以我做了一个分支,就像这样:
svn copy . https://my_svn_server/svn/blah/branches/my-branch
Run Code Online (Sandbox Code Playgroud)
...然后做了一个svn开关,并愉快地继续在那个分支工作.到目前为止,这么好,直到我对所有变化感到高兴,并希望将它们再次合并回主干.所以我将所有更改检入my-branch,然后仔细按照此处显示的步骤进行操作......这就是我遇到麻烦的地方.因为我从本地(客户端)存储库创建了my-branch,该存储库已经有大量(未签入的)未完成的更改,所以合并不包括与这些更改对应的差异,因此存在合并中有很多很多冲突,我必须手工解决 - 这是我不想做的事情,因为如果我搞砸了就会留下虫子进入的空间.
我尝试通过减少合并期间指定的修订号来包含缺失的差异,例如通过执行a
svn merge -r2818:2932 https://my_svn_server/svn/blah/branches/my-branch
Run Code Online (Sandbox Code Playgroud)
而不是预期的
svn merge -r2819:2932 https://my_svn_server/svn/blah/branches/my-branch
Run Code Online (Sandbox Code Playgroud)
...但是这没有用,因为我的分支在修订版2818中不存在,所以我只是得到一个错误:
svn: Unable to find repository location for 'https://my_svn_server/svn/blah/branches/my-branch' in revision 2818
Run Code Online (Sandbox Code Playgroud)
这就是事情的立场.我这次可以手动理清这个烂摊子,但我很好奇是否有办法处理这个问题,以便下次事情变得更好.
我能想到的一个方法是不通过复制本地(客户端)储存库,而是通过使SVN树干HEAD的副本,然后检查出我分支到一个单独的目录中创建我的分支,然后手动将我的本地(未签入)更改从trunk目录复制到my-branch目录,然后直接还原本地trunk ...但这也非常繁琐且容易出错.
当然有一种更好,更自动的方法来创建一个包含本地(未签入)更改的分支,然后将其合并回到主干中?
我试图从内联C++函数中获取特定类型的行为,我不确定是否有办法实现它.
我希望我的函数接受有符号或无符号的16位值作为参数,对该值执行操作,然后返回相同类型的值.如果参数的signed/unsigned-ness是不明确的(例如因为它是常量),那么编译器只需选择签名版本即可.这是一个玩具程序,显示我第一次尝试获取该行为:
#include <iostream>
#include <cstdint>
int16_t getValuePlusOne( int16_t x) {return x+1;}
uint16_t getValuePlusOne(uint16_t x) {return x+1;}
using namespace std;
int main(int, char **)
{
int16_t signedVal = -15;
uint16_t unsignedVal = 23;
cout << getValuePlusOne( signedVal) << endl; // works, yay!
cout << getValuePlusOne(unsignedVal) << endl; // works, yay!
cout << getValuePlusOne(1234) << endl; // COMPILE ERROR, ambiguous! D'oh!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以这几乎起作用,但它在getValuePlusOne(1234)上出错,因为1234是不明确的(它可以是有符号或无符号的).很公平,但我不想这样做.
所以这是我的第二次尝试:
#include <iostream>
#include <cstdint>
template <typename T> T getValuePlusOne(T val) {return val+1;}
using namespace std; …Run Code Online (Sandbox Code Playgroud) macos ×3
c ×2
c++ ×2
branch ×1
casting ×1
core-audio ×1
deprecated ×1
dock ×1
hierarchical ×1
indentation ×1
linux ×1
macos-carbon ×1
merge ×1
pointers ×1
popen ×1
python ×1
qt ×1
seh ×1
styles ×1
svn ×1
templates ×1
windows ×1