【发布时间】:2020-12-20 16:30:26
【问题描述】:
为了安全起见,我已经在我的 DLL 调用中使用了旧式函数指针,如下所示:
// DLL
typedef int (__stdcall* ty)();
void test(ty t)
{
if (t)
{
int r = t();
....
}
}
而我可以使用这个:
void test(std::function<int()> t)
{
}
然而,众所周知,后者使用type erasure。 std::function 不能是原始函数指针(因为它可以传递一个具有捕获的 lambda,因此不能是原始指针)。
因此,在 Visual Studio 中,使用包含 std::function 的函数签名的 DLL 版本在发布模式下在调试模式下从可执行版本中使用时会崩溃,反之亦然。即使它是调试或发布模式,行为也不相同。有时它会崩溃,有时它会工作。
是否存在定义的运行时行为,我们可以依赖它来使用std::function?或者这是编译器专门根据我传递给它的内容而专门编译的东西,因此不能预先假定运行时行为?
在汇编级别,预编译单元上的函数签名必须是已知的。据我所知std::function runtime 实现没有很好的定义。
所以,例如,当我在编译时,那么
void test(std::function<int()> t)
可以通过类型擦除接受任何参数,如[]() -> int, [&]() -> int, [=]() -> int 等。但是,当这是预编译的,因此只在运行时,可以接受什么? std::function 是如何实现的?使用类指针?有没有明确的方法?
我不是在寻找一个必然与 VS 相关的解决方案,而是std::function 的标准定义,如果有的话。
【问题讨论】:
-
我不确定我是否理解这个问题。 Debug 和 Release 组件不能混合的原因有很多,不仅仅是这个。
-
@PaulSanders 我编辑过,调试/发布就是一个例子。当实际使用任何预编译的内容时,它也会失败。主要思想是了解std::function的运行时实现是如何定义的。
-
类型擦除是关于实现的,你想对语言的指定行为/含义说什么?
标签: c++