我不知道托管类指向的函数对象的生命周期.std::function 是本机对象并遵循本机 C++ 规则.将指针放在托管包装器中不会使其被垃圾收集.该对象似乎已被删除,托管类保留了一个悬空指针.是的,您的术语不准确,但您已正确诊断出问题.看一看:void dispatchEvent(std::function processEvent){Iface::Wrapper 包装器;wrapper.callback = &processEvent;wrapper.PassCallback();}processEvent 是函数参数,一个通过值传递的 std::function 对象.创建并存储在参数中的副本一直存在到作用域结束.它具有自动存储期限.当函数返回时,所有局部变量,包括函数参数,都会被销毁(不是删除").您需要动态分配(副本)std::function 对象,例如:typedef std::functioncbfn;wrapper.callback = new cbfn(processEvent);现在你有内存泄漏,但至少你没有在它被销毁后使用它.如果您只制作少数这些对象,泄漏甚至可能是可以接受的.通常,您应该在包装器上实现 IDisposable 并让 Dispose 方法执行 delete callback;.在 C++/CLI 中,您使用析构函数语法来实现这一点.~Wrapper(){删除回调;回调 = nullptr;}I have passed as callback a C++ member function to a C# project through a C++/CLI wrapper (this works fine). The C# project is going to call this delegate when receiving data from another .exe process: an event will be raised and a method will call this callback. So, I needed to "save" this Action delegate using an static instance of a C# class already created. I got the following code:// C++ unmanaged functionWRAPPER_API void dispatchEvent(std::function<void(int)> processEvent){ Iface::Wrapper wrapper; wrapper.callback = &processEvent; wrapper.PassCallback();}//C++ Managed public ref class Wrapper { public: std::function<void(int)>* callback; void ReturnToCallback(int data) { (*callback)(data); } void PassCallback() { StartGenerator^ startGen = gcnew StartGenerator(gcnew Action<int>(this, &Wrapper::ReturnToCallback)); } };// C#public class StartGenerator{ private Communication comm; public StartGenerator(Action<int> callback) { comm = Communication.Instance; comm.callback = callback; }}If I call the Action delegate in StartGenerator method, the C++ function is properly executed. However, my goal was saving the delegate to be able to call it afterwards, when data is received from another .exe process. When this data arrives, an event is raised and callback is called from the event method. It is at this point when I get the following exception:I think I need to manage the lifetime of the std::function, I don't know about the lifetime of the function object being pointed to by the managed class. The object seems to be deleted and the managed class is left holding a dangling pointer. 解决方案 Yes, I told you as much when I told you to store a pointer in the managed wrapper, hereThe std::function is a native object and follows the native C++ rules. Putting a pointer in a managed wrapper won't make it garbage-collected.Yes, your terminology isn't exact but you've correctly diagnosed the problem. Take a look:void dispatchEvent(std::function<void(int)> processEvent){ Iface::Wrapper wrapper; wrapper.callback = &processEvent; wrapper.PassCallback();}processEvent is function argument, a std::function object passed by value. The copy made and stored in the argument lives until the end of scope. It has automatic storage duration. When the function returns, all the local variables, function arguments included, are destroyed (not "deleted").You will need to dynamically allocate (a copy of) the std::function object, like:typedef std::function<void(int)> cbfn;wrapper.callback = new cbfn(processEvent);Now you have a memory leak, but at least you aren't using the object after it's destroyed. If you only make a handful of these objects the leak might even be acceptable. In general, you should implement IDisposable on your wrapper and have the Dispose method do delete callback;. In C++/CLI you use destructor syntax to accomplish that.~Wrapper(){ delete callback; callback = nullptr;} 这篇关于执行存储的回调时出现 System.AccessViolationException 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-01 02:12