我有功能:
FARPROC PUDSClass::getFunction(LPSTR szName)
{
if(handleDLL == NULL)
{
return NULL;
}
return GetProcAddress(handleDLL, szName);
}
我正在尝试将其重写为lambda函数。
FARPROC lambda_decToStrHex = [&](LPSTR szName)
{
if (handleDLL == NULL)
{
return NULL;
}
return GetProcAddress(handleDLL, szName);
};
但是我得到类型“ int”和“ int(attribute(stdcall)*)()”不一致的错误。
如果我这样写,就可以了:
auto getFunction = [&](LPSTR szName)
{
return GetProcAddress(handleDLL, szName);
};
据我了解,lambda无法处理返回NULL或GetProcAddress(),但是为什么普通函数可以这样做?
答案 0 :(得分:3)
FARPROC lambda_decToStrHex = ...;
这将创建一个变量lambda_decToStrHex
,其类型为FARPROC
,根据documentation,其定义为
int (FAR WINAPI * FARPROC) ()
这是一个返回int且不接受任何参数的函数。这根本不适合您的lambda类型。
如果有的话,您需要一个lambda可以衰减到的正确类型的函数指针,一个接受C字符串并返回FARPROC
指针的函数(简而言之:指向函数返回函数指针的指针): >
FARPROC (*lambda_decToStrHex)(LPSTR) = ...;
唯一:您的 lambda 不能衰减到函数指针,因为它具有非空闭包:
... = [&](LPSTR name) { /* ... */ };
// ^ ^ uses dllHandle, which thus gets part of closure
因此,剩下的就是将lambda分配给您的lambda类型的变量,该变量可以通过auto
获得。
编辑:return NULL;
:
此处的“ Lambda”是一个红色鲱鱼,它不是lambda的问题,而是任何具有推论返回类型(auto f() { ... }
)的函数。 NULL
通常定义为(void*)0
(但外观也可能有所不同),因此在两个出口处您将获得两种不同的返回类型(void*
和FARPROC
) (在这种情况下)lambda。现在应该推算哪种返回类型?
起初,您完全不应该使用NULL
,它是来自C的宏,而C ++提供了关键字用于:nullptr
。唯一地,它无法解决问题,因为它具有自己的类型(std::nullptr_t
),但仍然与FARPROC
不同。然后,强制转换可以解决问题(实际上也可以与宏一起使用):
return static_cast<FARPROC>(nullptr);
现在两个出口点都具有相同的返回类型,我们很好。尾随返回类型实现相同的目的:
[&](LPSTR) -> FARPROC { ... }
nullptr
自动衰减到正确的指针类型(因此您不需要强制转换); NULL
宏,没有强制转换,并且取决于定义的方式,可以(但不一定)失败。
另一种解决方案是一个定义明确的出口点:
[&](LPSTR)
{
FARPROC function = nullptr;
if(dllHandle)
function = get();
return function;
}
那么为什么它可以正常使用?好吧,您显式指定了返回类型(FARPROC f(...)
),这等效于具有尾随的返回类型。此外,它已编译的事实和错误消息:
"int" and "int (attribute(stdcall)*)()"
^^^
显示您的编译器显然定义了NULL
,而没有进行void*
强制转换:
#define NULL 0
或类似的字符-和0
的文字也将衰减为空指针...
答案 1 :(得分:2)
由于您在常规函数中指定了返回类型FARPROC
,因此NULL
(0
,即int
类型)将隐式转换为FARPROC
类型(就是int (attribute(stdcall)*)()
)。
您可以使用->
通过lambda指定返回类型:
auto lambda_decToStrHex = [&](LPSTR szName) -> FARPROC
{
if (handleDLL == NULL)
{
return NULL;
}
return GetProcAddress(handleDLL, szName);
};