简短而简单的问题:我是新手boost::asio,我想知道是否有可能同时tcp::acceptor监听IPv4和IPv6连接.关于boost主页的教程显示如下:
_acceptor = new tcp::acceptor(_ioService, tcp::endpoint(tcp::v4(), 3456));
Run Code Online (Sandbox Code Playgroud)
始终使用特定协议指定端点.是否无法同时在同一端口上侦听IPv4和IPv6?
今天我正在调试我的一些构建一些ExpressionTrees的代码,将它们编译成可调用的Delegates,然后在需要时调用它们.在这样做时,我遇到了FatalExecutionEngineError代码的踩踏:

起初我有点震惊,因为我不知道我的表达式可能出现什么问题,他们看起来很好.然后我发现这只发生在以下情况:
Method A是一个静态方法,它被调用并生成ExpressionTree,它可能包含一个Expression.Call()to Method A.因此,在为ExpressionTree编译Lambda之后,Method B如果我在此方法中调用它,则生成的Delegate(让我们调用它)可能会导致递归...(Method A- > [Generated]Method B- > Method A).
......这在我的场景中是完全可能的.如上所述,我正在调试这段代码,所以我设置了一个断点Method A.
第一次Method A由常规代码调用,断点像往常一样.当Method B调用时,断点会再次出现,但一切都还可以.
但是一旦我通过踩到最后一行而与调试器进行第二次调用,FatalExecutionEngineError就会发生这种情况.
如果我在没有调试的情况下运行代码,或者不执行递归调用Method A,或者如果我不跳过方法的最后一行,则问题不会发生,并且我的表达式代码按预期执行.
我无法确定这是VS-Debugger或.NET Framework中的错误,还是我做了一些非常可怕的错误,只有在调试相关行时才会出现错误.
这是一个非常简单的示例代码,您可以开箱即用.我正在使用Visual Studio 2013 Prof更新4和.NET 4.5.1.只需设置断点DoSomething()并尝试直到最后 - 如果可以的话;)
任何人都可以确认一个错误,或者我的表情是不正确的吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ExpressionProblem
{
public class MainClass …Run Code Online (Sandbox Code Playgroud) 脚本
这应该是一项简单的任务,但由于某种原因,我无法按预期进行.我必须struct在反向P/Invoke调用(非托管调用托管代码)期间编组基本C++ .
只有bool在struct中使用时才出现这个问题,所以我只是将C++方面修改为:
struct Foo {
bool b;
};
Run Code Online (Sandbox Code Playgroud)
由于.NET默认情况下将布尔值编组为4字节字段,因此我将本机布尔值显式编组为1字节长度字段:
public struct Foo {
[MarshalAs(UnmanagedType.I1)] public bool b;
}
Run Code Online (Sandbox Code Playgroud)
当我使用以下签名和正文调用导出的托管静态方法时:
public static void Bar(Foo foo) {
Console.WriteLine("{0}", foo.b);
}
Run Code Online (Sandbox Code Playgroud)
我打印出正确的布尔alpha表示.如果我使用更多字段扩展结构,则对齐是正确的,并且在编组后数据不会损坏.
问题
出于某种原因,如果我不将此编组struct作为参数传递,而是通过值传递返回类型:
public static Foo Bar() {
var foo = new Foo { b = true };
return foo;
}
Run Code Online (Sandbox Code Playgroud)
应用程序崩溃时出现以下错误消息:
如果我更改托管结构以保持byte而不是abool
public struct Foo {
[MarshalAs(UnmanagedType.I1)] public byte b;
}
public static Foo Bar() {
var foo = new …Run Code Online (Sandbox Code Playgroud) 我想知道,任何人都可以在技术层面解释什么是R值参考?我的意思是:当创建R值引用时,汇编程序级别会发生什么.
对于一个小测试,看看里面发生了什么,我写了下面的代码:
char c = 255;
char &c2 = c;
char &c3 = std::move(c);
Run Code Online (Sandbox Code Playgroud)
我知道为'c'创建R值引用是没有意义的,但仅仅是为了测试我还是做了它,看看它做了什么.这是结果:
unsigned char c = 255;
mov byte ptr [c],0FFh
unsigned char &c2 = c;
lea eax,[c]
mov dword ptr [c2],eax
unsigned char &&c3 = std::move(c);
lea eax,[c]
push eax
call std::move<unsigned char &> (0ED1235h)
add esp,4
mov dword ptr [c3],eax
Run Code Online (Sandbox Code Playgroud)
我到目前为止还不是专家,但在我看来,在这种情况下,'c3'最后是对'c'的常规引用.
如果我将R-Value引用直接绑定到临时(char && c3 = 255),汇编程序的最后一位会发生变化:
unsigned char &&c3 = 255;
mov byte ptr [ebp-29h],0FFh
lea eax,[ebp-29h]
mov dword ptr [c3],eax
Run Code Online (Sandbox Code Playgroud)
从这个变化的外观来看,我假设c3实际上仍然是对某个保存值为255的内存位置的引用.所以它是一个常规引用 - …
我目前正在尝试为一个非常基本的游戏引擎实现一个"加载线程",它负责加载例如纹理或音频,同时主线程保持呈现正确的消息/屏幕,直到操作完成或甚至在加载时渲染常规游戏场景较小的对象出现在背景中.
现在,我到目前为止还没有OpenGL专家,但是当我实现这样一个"加载"机制时,我很快发现OGL不喜欢从非常多的创建的线程访问渲染上下文.我用Google搜索,解决方案似乎是:
"在线程上创建第二个渲染上下文,并与主线程的上下文共享"
这个问题是我使用SDL来处理我的窗口管理和上下文创建,据我所知,在检查API时,没有办法告诉SDL在彼此之间共享上下文:(
我得出结论,我的案例的最佳解决方案是:
方法A)改变SDL库以支持与平台特定功能的上下文共享(wglShareLists()和glXCreateContext()我假设)
方法B)让"加载线程"仅将数据加载到存储器中并将其处理为OpenGL友好格式并将其传递给主线程,例如负责将纹理上载到图形适配器.当然,这仅适用于需要完成有效OpenGL上下文的数据
第一种解决方案是我认为效率最低的解决方案.我真的不想破坏SDL,除此之外,我读到上下文共享不是一个高性能的操作.所以到目前为止,我的下一步将采用第二种方法.
编辑:关于"高性能操作":我读错了文章,实际上并不是表现密集.本文建议使用第二个上下文将CPU密集型操作转移到第二个线程.对不起
在完成所有这些介绍之后,如果有人能够对以下问题给我一些提示和评论,我将非常感激:
1)有没有办法与SDL共享上下文,无论如何这样做会有什么好处吗?
2)是否还有其他更"优雅"的方式来加载我可能错过或未考虑的后台数据?
3)我认为采用方法B的意图是否是一个不错的选择?在我的主线程上阻止渲染的OpenGL操作仍会有轻微的开销,或者它可以被忽略的那么小?
我想知道,是否有可能同时在多个GPU上运行多窗口OpenGL应用程序?更具体地说,假设我创建了一个具有两个窗口的应用程序,每个窗口彼此共享它的GL上下文.现在,如果我将其中一个窗口从显示器1(在GPU 1上运行)移动到显示器2(在GPU 2上运行),这实际上是否有效?单独分享上下文是否可以解决问题?
我的第一个猜测是否定的.如果这真的不那么简单,有没有办法实现这一目标?我还可以想象这取决于两个GPU是否由相同的驱动程序控制(更糟糕的是,让机器有ATI和nVidia卡,两者都支持不同的GL版本).
我很感激有关这个主题的任何见解,纯信息,因为我快速谷歌搜索后找不到任何东西.有谁知道可能性?
编辑:顺便说一句,不幸的是我目前没有多台GPU可用的机器,所以我会测试一下.
我最近在C++中编写了一个DLL-Injector,其要求如下
很快我注意到,Injector 中GetProcAddress("LoadLibraryA")的调用返回一个"不可用"句柄,因为32位目标加载了另一个kernel32.dll,并且函数的地址不同,因此注入失败(无法使用返回的地址/句柄启动远程线程).此外,32位进程将kernel32.dll加载到不同的基址,这使得创建远程线程更加不可能.
为了说清楚我的意思,会发生以下情况:
当从64位进程注入64位进程,从32位注入32位时,通常没有问题,因为kernel32.dll(很可能)在相同的基地址加载并且可以使用相同的函数地址 - 到目前为止,这是我的解释.在这种情况下,条件不同.
为了解决这个问题,我做了以下步骤:
这种方法实际上运行得很好,但我无法摆脱这是总开销的想法,并且必须有一个更简单的解决方案来从64位注入器注入32位目标.
我有两个问题,如果可以在这里回答,我将非常感激:
任何答案都非常感谢,谢谢!
编辑:哦,我的天啊...我刚刚意识到,我在最初的帖子中描述了错误的情况.INJECTOR是64位,TARGET是32位(最初是另一种方式,但我已经纠正了它).Ben Voigt在下面的评论完全正确,对EnumProcessModulesEx的调用将失败.一个大大的抱歉,这种混乱:(
我目前在C++ 0x中编写事件处理程序系统.通过传递可以存储在std::function对象中的任何类型的函数/方法来注册每个事件的"处理程序"(可以有多个处理程序).这是使用重载的+ =运算符以C#样式完成的.我的事件类看起来基本上像这样(剥离以获得更好的可读性):
template<typename THandlerReturn, typename THandlerArgs...>
class Event {
public:
typedef THandlerReturn(HandlerSignature)(THandlerArgs...);
typedef THandlerReturn(*HandlerFuntionPtr)(THandlerArgs...);
typedef typename std::function<HandlerSignature> HandlerFunction;
void operator += (HandlerFunction handler) {
_handlers.push_back(handler);
}
// Some other methods for calling all handlers, ctors, etc.
private:
std::vector<HandlerFunction> _handlers;
};
Run Code Online (Sandbox Code Playgroud)
现在我有另一个内部方法从std::function存储在向量中的对象中检索实际的函数指针.它基本上试图做这样的事情:
// Preceeding: Get an iterator 'it' from the vector
HandlerFunctionPtr pt2func = it->target<HandlerSignature>();
Run Code Online (Sandbox Code Playgroud)
此时,当我在我的应用程序中使用Event类时,编译失败了.使用GCC 4.7版本我得到以上行的以下错误消息:
error: expected primary-expression before '>' token
error: expected primary-expression before ')' token
Run Code Online (Sandbox Code Playgroud)
我已经使用target<>()Method 进行了一些测试,并且以下工作完美,假设返回类型是void并且有一个类型的参数int …
目前,我在使全局 keyhook 在 Windows 7 64 位操作系统上运行时遇到一些麻烦。现在我知道 Stackoverflow 上已经有很多关于这个主题的帖子,但没有一个能给我一个可以使用的答案,或者我不太明白这些帖子中的问题是如何解决的。
因此,我将尝试解释我所遇到的困难,并希望任何人都可以帮助我或为我指明正确的方向。
基本上我的目标是拦截 CTRL+C 和 CTRL+V 键盘输入以实现某种剪贴板管理器。因此,我当前的尝试是注册一个系统范围的WH_KEYBOARD挂钩,根据我的需要处理截获的击键。
我在 64 位 Windows 7 操作系统上运行钩子,这就是问题开始的地方。对我来说很明显,32 位 Hook DLL 会给 64 位进程带来问题,反之亦然。因此,我生成了包含该钩子的库的 x86 和 x64 版本,以及该钩子的调用者(调用 的那个SetWindowsHookEx()),两者都具有不同的文件名,如文档所示。
但现在怎么办?如果我将 64 位 DLL 设置为系统范围的挂钩,则所有 32 位应用程序在聚焦时按下某个键后就会开始挂起。同样的事情,当我应用 32 位挂钩时,我的 Windows 几乎无法使用,因为它explorer.exe是 64 位的。如果我设置了两个钩子,我的系统就会有效地处于停滞状态,进行全局“bitness”战斗。
现在我假设问题是由 64 位挂钩 DLL 试图注入 32 位进程等引起的,这当然是无意义的。但对于这种情况,文档SetWindowsHookEx()说明如下:
由于挂钩在应用程序的上下文中运行,因此它们必须与应用程序的“位数”匹配。如果 32 位应用程序在 64 位 Windows 上安装全局挂钩,则该 32 位挂钩将被注入到每个 32 位进程中(适用通常的安全边界)。在 64 位进程中,线程仍标记为“挂钩”。但是,由于 32 位应用程序必须运行挂钩代码,因此系统会在挂钩应用程序的上下文中执行挂钩;具体来说,在调用 SetWindowsHookEx 的线程上。这意味着挂钩应用程序必须继续发送消息,否则可能会阻止 …
c++ ×6
c# ×2
opengl ×2
winapi ×2
32bit-64bit ×1
assembly ×1
boost-asio ×1
c++11 ×1
debugging ×1
dll ×1
expression ×1
function ×1
gpu ×1
hook ×1
interop ×1
ip-address ×1
ipv4 ×1
ipv6 ×1
keyhook ×1
marshalling ×1
pinvoke ×1
sdl ×1
sharing ×1
target ×1
templates ×1