将QML信号连接到常规C++插槽很容易:
// QML
Rectangle { signal foo(); }
// C++ old-style
QObject::connect(some_qml_container, SIGNAL(foo()), some_qobject, SLOT(fooSlot()); // works!
Run Code Online (Sandbox Code Playgroud)
但是,无论我尝试什么,我似乎都无法连接到C++ 11 lambda函数槽.
// C++11
QObject::connect(some_qml_container, SIGNAL(foo()), [=]() { /* response */ }); // fails...
QObject::connect(some_qml_container, "foo()", [=]() { /* response */ }); // fails...
Run Code Online (Sandbox Code Playgroud)
两次尝试都失败并出现函数签名错误(没有QObject :: connect重载可以接受这些参数).但是,Qt 5文档暗示这应该是可能的.
不幸的是,Qt 5示例总是将C++信号连接到C++ lambda插槽:
// C++11
QObject::connect(some_qml_container, &QMLContainer::foo, [=]() { /* response */ }); // works!
Run Code Online (Sandbox Code Playgroud)
这种语法不适用于QML信号,因为QMLContainer :: foo签名在编译时是未知的(并且手动声明QMLContainer :: foo会破坏首先使用QML的目的.)
我正在尝试做什么?如果是这样,QObject :: connect调用的正确语法是什么?
opengl32.dll和gdi32.dll之间重复以下功能:
[opengl32.dll] / [gdi32.dll]
wglChoosePixelFormat / ChoosePixelFormat
wglDescribePixelFormat / DescribePixelFormat
wglGetPixelFormat / GetPixelFormat
wglSetPixelFormat / SetPixelFormat
wglSwapBuffers / SwapBuffers
Run Code Online (Sandbox Code Playgroud)
我一直在寻找一个答案很长一段时间,但似乎没有任何具体的信息,为什么会这样,他们的确切区别是什么.
在OpenGL的常见问题,节5.190,表明这些功能都没有功能上相同的:
为确保OpenGL的正确操作,请使用ChoosePixelformat,DescribePixelformat,GetPixelformat,SetPixelformat和SwapBuffers,而不是wgl等效项,wglChoosePixelformat,wglDescribePixelformat,wglGetPixelformat,wglSetPixelformat和wglSwapBuffers.在所有其他情况下,使用可用的wgl函数.使用五个wgl函数只是开发人员运行时链接到OpenGL驱动程序的兴趣.
"运行时链接到OpenGL驱动程序"是否意味着绕过opengl32.dll并直接加载ICD?
名为"Mesa3D不喜欢我的上下文创建代码"的stackoverflow线程似乎强化了这一点.
另一个在C#中名为wglCreateContext但不在托管C++中的 stackoverflow线程表明,在使用GDI函数时,必须在gdi32.dll之前加载opengl32.dll,否则可能会导致运行时失败(错误:2000).
我自己的测试表明,如果调用这些函数的opengl32/wgl版本,某些系统(Nvidia,但不是Intel或Parallels VM)会出现"error:2000" .更改为GDI版本会清除此问题,但使用LoadLibrary("opengl32.dll")似乎不会更改任何内容.
有没有人研究过这些WGL和GDI函数之间的区别?显然存在某种形式的差异,我试图了解在哪种情况下应该使用哪个版本以及如果使用错误版本会有什么潜在的缺陷.
编辑:wayback机器打开一个网页,描述ICD的直接加载如何工作.这显然需要在Voodoo 1/2天内,当2d和3d加速器是具有单独ICD的两个不同硬件(正常的opengl32.dll + ICD机制无法处理时).地震1和2显然会加载ICD直接因此而产生.
但是,下面的帖子显示AMD ICD不会导出wgl变体,这与此想法相矛盾.
有有是某个人或某个地方,在那里,持有的钥匙,这方面的知识.
编辑2:从上面的网页上得到了最清晰的建议:
"因此,如果您使用的是名为OPENGL32.DLL你一个OpenGL驱动程序 必须调用GDI函数,如果你没有使用一个名为OPENGL32.DLL你的驱动程序必须不调用GDI函数."
但是,这与AMD ICD不输出wgl功能的事实如何相符呢?
编辑2:显然Mesa3d导出WGL符号,如下所示:http://cgit.freedesktop.org/mesa/mesa/tree/src/mesa/drivers/windows/gdi
这是有道理的,因为Mesa3d不应该用作ICD.这符合上面链接的Mesa3d线程中的模式:它们的调用没有通过Microsoft的opengl32.dll路由,因此gdi函数失败,但是Mesa3d正在导出wgl*函数,所以这些仍然有效.但是,这是特定于Mesa3d的 - 如果您尝试直接使用AMD的ICD,该方法将失败.
在测试应用程序性能时,我遇到了一些非常奇怪的GC行为.简而言之,GC甚至在没有运行时分配的空程序上运行!
以下应用程序演示了此问题:
using System;
using System.Collections.Generic;
public class Program
{
// Preallocate strings to avoid runtime allocations.
static readonly List<string> Integers = new List<string>();
static int StartingCollections0, StartingCollections1, StartingCollections2;
static Program()
{
for (int i = 0; i < 1000000; i++)
Integers.Add(i.ToString());
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
static void Main(string[] args)
{
DateTime start = DateTime.Now;
int i = 0;
Console.WriteLine("Test 1");
StartingCollections0 = GC.CollectionCount(0);
StartingCollections1 = GC.CollectionCount(1);
StartingCollections2 = GC.CollectionCount(2);
while (true)
{
if (++i >= Integers.Count)
{
Console.WriteLine();
break; …
Run Code Online (Sandbox Code Playgroud) 请考虑以下简单代码:
using System;
class Test
{
delegate int FooDelegate(int i);
FooDelegate Foo = FooImplementation;
static int FooImplementation(int i)
{
return i + 1;
}
public static void Main()
{
Foo(1);
}
}
Run Code Online (Sandbox Code Playgroud)
我想做的是将一些调试代码注入到Foo委托中,这相当于:
FooDelegate Foo = delegate(int i)
{
try
{
DebugPrologue();
return FooImplementation(i);
}
finally
{
DebugEpilogue();
}
};
Run Code Online (Sandbox Code Playgroud)
扭曲的是我必须能够在运行时执行此操作,因此编译时和后处理方法是不可能的.
我的初始方法使用Delegate.Combine()将序言和结尾方法添加到Foo委托.唉,这不会起作用,因为它会回报价值.
我目前的想法是使用System.Reflection.Emit和DynamicMethod作为潜在的解决方案.据我所知,我需要为FooImplementation获取MethodInfo,获取它的MethodBody,将其转换为DynamicMethod并将try-finally块注入其中.
不幸的是,我完全不知道该怎么做.谁愿意伸出援助之手?或者你有另一个(最好更简单)的想法?
编辑:这里的用例是调试OpenGL绑定(http://www.opentk.com).我们必须注入2226种具有完全不同参数的方法,因此需要采用一般方法.
考虑以下场景: - 2500的上游存储库存储在SVN中 - git用户A将存储库导入git并提交1个补丁 - git用户B将存储库导入git并提交1个补丁 - git用户A想要合并补丁来自git用户B.
在这种情况下,如果用户A使用git merge
,那么git历史将被公共svn提交污染(即代替2502提交,历史将包含2501 + 2501 = 5002提交!)
如果用户A使用git rebase
,则git历史记录将是正确的(2502提交).这在这个简单的场景中工作得很好,但是如果用户A和用户B每次都没有1次提交,那么就会出现奇怪的复杂情况:git rebase -Xours
失败并显示以下消息:
First, rewinding head to replay your work on top of it...
fatal: Could not parse object '98d7cd83de321e737b22240752cd178622d29406^'
Unknown exit code (128) from command: git-merge-recursive 98d7cd83de321e737b22240752cd178622d29406^ -- HEAD 98d7cd83de321e737b22240752cd178622d29406
Run Code Online (Sandbox Code Playgroud)
您可以使用以下github存储库重现此问题:
git clone https://github.com/opentk/opentk
cd opentk
git remote add mono https://github.com/mono/opentk
git fetch mono
git checkout -b integrate
git rebase -Xours mono/rodo-consolidate-opentk
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么会这样?有任何想法如何解决这个问题?
我正在寻找一个正则表达式,以从一组xml文档中剥离以下doctype声明:
<!DOCTYPE refentry [ <!ENTITY % mathent SYSTEM "math.ent"> %mathent; ]>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook MathML Module V1.1b1//EN"
"http://www.oasis-open.org/docbook/xml/mathml/1.1CR1/dbmathml.dtd">
Run Code Online (Sandbox Code Playgroud)
这是关于stackoverflow和其他地方的一个非常普遍的问题,但是实际上没有一个答案能够同时解决这两种情况。
我的幼稚方法<!DOCTYPE((.|\n|\r)*?)(\"|])>
将正确地匹配第二种情况,但是在第一种情况下会失败(它在第一种情况下停止">
并且%mathen; ]>
不匹配。)如果我尝试使正则表达式更加贪婪,它将尝试消耗整个文档。
完整的测试用例: