指向成员的指针对托管类无效
A pointer to member is not valid for a managed class
我创建了一个库,其中一个公开的函数接受类型为void(*fun_ptr)(int)
的函数指针。
函数语法为:
start_server(char *devices, char *folder, int number, int timeout, void(*status_of_server)(int));
这适用于正常的C++函数,例如void getStatus(int n);
但是当我在GUI应用程序的Visual C++环境中使用它们时,我收到此错误:
指向成员的指针对托管类无效
start_server(&devs, &base, 1, 0, &TestApplication::MainWindow::StatusOfServer );
其中StatusOfServer
在可用于 UI 管理的MainWindow
类中定义。
private: void TestApplication::MainWindow::StatusOfServer(int n)
{
this->progressBar->Value = n;
}
处理这个问题的正确方法是什么?
这种奇怪行为的原因是每个成员函数都隐式地在其签名后附加了一个指向其类型的指针,例如:
#include <iostream>
struct S
{
int i;
void doSth() { std::cout << i << std::endl; }
};
int main()
{
S s{1};
s.doSth();
auto member_f = &S::doSth;
(s.*member_f)();
}
doSth()
有一个隐藏的参数,所以不能像常规函数一样调用它。在您的示例中,情况类似 - 您尝试调用成员函数,就好像它是一个普通的自由函数一样,这将不起作用。通常在请求函数指针的 API 中,函数可以将void*
作为参数,这允许您编写一个包装器,将指针强制转换为正确的类型,然后在指向类的实例上调用成员函数。但是,从上面显示的代码来看,您无法将void*
传递到函数中,因此您可能具有某种全局状态(例如,使该函数成为静态函数并使其仅对静态数据工作(。
一种解决方案是围绕托管包装器创建一个小型的非托管包装函数:
void wrapStatusOfServer(int n) {
TestApplication::MainWindow::StatusOfServer(n)
}
并获取指向包装器的指针
start_server(&devs, &base, 1, 0, &wrapStatusOfServer);
另一种解决方案:将start_server
转换为托管代码,并使用委托而不是函数指针:https://learn.microsoft.com/en-us/cpp/dotnet/how-to-define-and-use-delegates-cpp-cli?view=vs-2017
C++/CLI 充满了此类问题,其中托管和非托管代码和数据几乎但不完全可互操作。
相关文章:
- 如何实现容纳整数和无效指针的双向链表?
- 在基数排序中,我得到 munmap_chunk():无效指针和中止(核心转储).为什么?
- 应用地址清理器后,免费无效指针消失
- C++ 在具有数组成员的类上无效指针/双精度释放
- 不断得到分段错误和free()无效指针
- 使用无效指针初始化指针声明符的行为是否未定义?
- 结构作为参数的函数产生错误:free():无效指针:0x00007efd47b
- 无效指针、隔离标识符等
- c++ 无效指针从空闲列表中取消排队
- C++ munmap_chunk(): 无效指针:
- 为什么我的简单C++程序使用队列和 fstream 错误到无效指针
- 无效指针和非初始化的指针之间的差异
- 如何用无效指针初始化unique_ptr的向量
- 地址清理器在静态强制转换无效指针时报告错误
- MS4:Free(Free()无效指针0xB74E74E0 ***
- ***检测到的GLIBC *** MS2:free():无效指针:0xB7526FF4 ***
- 无效指针功能的输出
- 有人能告诉我这是如何在main()中实现的吗?(关于无效指针的问题)
- C++11使用智能指针,但得到无效指针
- 无效指针的相关性