请问有人可以给我一些创建MS winapi函数函数指针的技巧吗?我正在尝试为DefWindowProc(DefWindowProcA/DefWindowProcW)创建一个指针,但是收到此错误:
LRESULT (*dwp)(HWND, UINT, WPARAM, LPARAM) = &DefWindowProc;
error C2440: 'initializing' : cannot convert from
'LRESULT (__stdcall *)(HWND,UINT,WPARAM,LPARAM)'
to 'LRESULT (__cdecl *)(HWND,UINT,WPARAM,LPARAM)'
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚我需要使用什么因为我不习惯MS ascii/wide宏.顺便说一下,我正在创建一个快速入侵的函数指针,不幸的是我没有时间解释原因 - 但无论如何,我认为这个问题对于需要创建winapi函数指针的人会有所帮助.
这段代码有效,但我担心这是不好的做法(并且不遵守unicode/ascii编译选项).我应该定义两个规格吗?
LRESULT (__stdcall* dwp)(HWND, UINT, WPARAM, LPARAM) = &DefWindowProc;
Run Code Online (Sandbox Code Playgroud)
这更好(感谢nobugz):
WNDPROC dwp = DefWindowProc;
Run Code Online (Sandbox Code Playgroud) 我创建了一个Timer类,当计时器到期时必须调用一个回调方法.目前我使用普通函数指针(它们被声明为void(*)(void),当Elapsed事件发生时,函数指针被调用.
是否可以使用也具有签名void(AnyClass ::*)(void)的成员函数执行相同的操作?
谢谢你的队友.
编辑:此代码必须在Windows上以及在实时操作系统(VxWorks)上工作,因此不使用外部库会很棒.
EDIT2:只是为了确定,我需要的是有一个Timer类,它在构造函数中接受一个参数,不带参数,然后返回void的"AnyClass.AnyMethod".我必须存储这个参数,后者在代码中只执行此变量指向的方法.希望很清楚.
下面使用一个简单的函数指针,但如果我想存储该函数指针怎么办?在这种情况下,变量声明会是什么样的?
#include <iostream>
#include <vector>
using namespace std;
double operation(double (*functocall)(double), double wsum);
double get_unipolar(double);
double get_bipolar(double);
int main()
{
double k = operation(get_bipolar, 2); // how to store get_bipolar?
cout << k;
return 0;
}
double operation(double (*functocall)(double), double wsum)
{
double g = (*functocall)(wsum);
return g;
}
double get_unipolar(double wsum)
{
double threshold = 3;
if (wsum > threshold)
return threshold;
else
return threshold;
}
double get_bipolar(double wsum)
{
double threshold = 4;
if (wsum > threshold)
return …
Run Code Online (Sandbox Code Playgroud) 我在某处读到,如果捕获列表为空,则lambda函数应衰减为函数指针.我现在唯一能找到的参考是n3052.使用g ++(4.5和4.6)它可以按预期工作,除非lambda在模板代码中声明.
例如,以下代码编译:
void foo() {
void (*f)(void) = []{};
}
Run Code Online (Sandbox Code Playgroud)
但它在模板化时不再编译(如果foo
在其他地方实际调用):
template<class T>
void foo() {
void (*f)(void) = []{};
}
Run Code Online (Sandbox Code Playgroud)
在上面的参考中,我没有看到这种行为的解释.这是g ++的临时限制,如果没有,是否有(技术)理由不允许这样做?
我需要一些C++帮助!
我正在为一个基于文本的小游戏编写一个命令解析器,我遇到了一些问题.解析器应该读取并解析播放器输入的命令.
对此最明显和直接的解决方案可能是这样的(用伪代码编写):
command <- read input from the player
if command == COMMAND1
do command1
else if command == COMMAND 2
do command2
...
Run Code Online (Sandbox Code Playgroud)
我正在用C++编写,所以我想我可以通过使用关联映射和函数指针来解决这个问题.我对使用函数指针并不熟悉,所以这可能就是我遇到问题的原因.我想要做的是,有一些等待输入的循环,解析插入的输入,并根据给定的命令调用函数.这里有一些C++ - ish伪代码描述了我的想法:
while(1) {
cin >> input;
char * tok = strtok(input, " ")
functionpointer fptr = command_map.find(tok);
... // here, I get stuck on what to do..
}
Run Code Online (Sandbox Code Playgroud)
所以我希望我能清楚地说明我想要发生什么.玩家本可以输入类似的内容
> go south
Run Code Online (Sandbox Code Playgroud)
我可以用以下代码完成代码:
destination = strtok(NULL, " ");
fptr(destination);
Run Code Online (Sandbox Code Playgroud)
基本上,从映射返回的值将是执行命令"go"的函数,并且该函数显然需要一个参数,即目标.同样,这是一些C++ - 伪代码.所以我得到了命令"go".但是现在说我想要有以下命令:
> attack troll with sword
Run Code Online (Sandbox Code Playgroud)
现在我觉得我需要做一些事情:
while(1) {
cin >> input; …
Run Code Online (Sandbox Code Playgroud) 可能重复:
函数引用
我在一本书中找到了这个代码,
typedef int (&foo)(int,int);
这是什么意思 ?这是对函数的引用吗?如果是,为什么用它?它与指向这样的函数的指针有什么不同.
typedef int (*foo)(int,int);
这只是C++中不是C的增强吗?
编辑:
#include <iostream>
#include <typeinfo>
using namespace std;
int f (int , int ) {return 0;}
int main() {
int (&foo)(int,int) = f;
int (*fp)(int,int) = f;
std::cout<<typeid(foo).name()<<std::endl<<typeid(fp).name();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我打印的类型foo
和fp
它给了这样的事情:
FiiiE
PFiiiE
什么是E
最后的.为什么foo
是F
同时fp
是PF
?
考虑以下课程:
class Foo
{
private:
void bar(const size_t);
public:
void foo();
};
Run Code Online (Sandbox Code Playgroud)
现在Foo::foo()
应该启动线程执行bar
,所以这是它的实现方式:
void Foo:foo()
{
auto handle = std::async(std::launch::async, &Foo::bar, this, 0);
handle.get();
}
Run Code Online (Sandbox Code Playgroud)
这与g ++ - 4.6.3完美配合,但与g ++ - 4.5.2无关,错误信息是
include/c ++/4.5.2/functional:180:9:错误:必须使用».«或» - > «使用_Tp = void(Foo ::*)(long unsigned int)调用»std :: declval中的指向成员函数,typename std :: add_rvalue_reference <_Tp> :: type = void( Foo :: &&)(long unsigned int)(...)«,例如»(... - > std :: declval with _Tp = void(Foo ::*)(long unsigned int),typename std :: add_rvalue_reference <_Tp> :: type …
亲爱的StackOverflowers,
我在Microsoft Visual Studio C++ 2012上编写了一段简单的代码:
int add(int x, int y)
{
return x + y;
}
typedef int (*func_t)(int, int);
class A
{
public:
const static func_t FP;
};
const func_t A::FP = &add;
int main()
{
int x = 3;
int y = 2;
int z = A::FP(x, y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器生成以下代码:
int main()
{
000000013FBA2430 sub rsp,28h
int x = 3;
int y = 2;
int z = A::FP(x, y);
000000013FBA2434 mov edx,2
000000013FBA2439 lea ecx,[rdx+1] …
Run Code Online (Sandbox Code Playgroud) 我想有一个嵌套值的模板,应该由给定的初始化函数初始化:
template <typename T, T(INIT)()> struct Foo
{
T value = INIT();
};
Run Code Online (Sandbox Code Playgroud)
它可以这样使用:
// Some random type only instanceable through factory()
struct Bar
{
int bar{};
private:
// The only way to create a Bar is through factory()
friend Bar factory();
Bar() {};
};
Bar factory() { return {}; }
Foo<Bar, factory> foo;
Run Code Online (Sandbox Code Playgroud)
但是,如果没有提供函数,模板应该尝试默认初始化嵌套值,所以我试图专门化模板:
template <typename T> struct Foo<T, nullptr>
{
T value{};
};
Run Code Online (Sandbox Code Playgroud)
我的想法是这样使用它:
struct Baz{};
Foo<Bar, factory> foo; // Nested Bar have Bar::bar initialized through factory function. …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个包含许多函数对象的库,这些函数对象的类具有多个operator()
重载,这些重载不依赖于类的状态而不会改变它.现在,我试图让我的代码使用许多旧式API(它不是随机需要,我实际上不得不处理这样的API),因此决定使函数对象可以转换为任何一个对应的函数指针重载.在某些时候,我意识到我有太多这样的转换来运行指针运算符,我理论上应该能够编写一个可变转换运算符.这是一个实现这种可变参数运算符的类:
struct foobar
{
template<typename... Args>
using fptr_t = void(*)(Args... args);
template<typename... Args>
operator fptr_t<Args...>() const
{
return [](Args... args) {
// Whatever
};
}
};
Run Code Online (Sandbox Code Playgroud)
如您所见,我使用lambda转换函数指针来实现转换运算符,这不是问题,因为我拥有的每个函数对象都是无状态的.目标是能够使用如下类:
int main()
{
void(*foo)(int) = foobar();
void(*bar)(float, double) = foobar();
}
Run Code Online (Sandbox Code Playgroud)
g ++使用预期的语义编译此代码没有问题.但是,clang ++ 拒绝它时出现模板替换失败错误:
Run Code Online (Sandbox Code Playgroud)main.cpp:21:11: error: no viable conversion from 'foobar' to 'void (*)(int)' void(*foo)(int) = foobar(); ^ ~~~~~~~~ main.cpp:11:5: note: candidate function [with Args = int] operator fptr_t<Args...>() const ^ 1 error generated.
请注意,只要不涉及可变参数模板,clang ++对此类转换运算符没有任何问题.如果我使用单个模板参数,编译代码就没有问题.现在,编译器是接受还是拒绝上面的代码?
c++ function-pointers language-lawyer variadic-templates c++14