KN_Michael Posted November 2, 2021 Share Posted November 2, 2021 (edited) Background We do push handles and some data into a tree structure and do use those handles quite often for some calculations and updates. This happens inside the idle event. The problem is, that FAST undo/redos SOMETIMES (its very hard to replicate) lead to handles being invalid in the sense of that the handle is not a null pointer but accessing the handle crashes the application with an invalid access exception. This tree data is cleaned and recreated on each file change/open so we only hold handles of the current active document inside the tree. Question Is there a way to validate if a handle is valid? I'd need something like following: bool valid = handle != NULL && gSDK->IsValidHandle(handle) But the second part does not exist... Any ideas how to solve this? Edited November 2, 2021 by KN_Michael Quote Link to comment
Nicolas Goutte Posted November 2, 2021 Share Posted November 2, 2021 I do not know a definitive answer to this. We do have our problems with invalid handles at times too. You can check not only that the handle is a nullptr but its dereference (*handle) too. However that is not enough either. The next step is to check its the parent layer return for that object. The layer and its parent should not be null. (Not sure if this is valid for symbols, because in in our code, why have extra code for symbols too.) Quote Link to comment
Maarten DE Posted November 3, 2021 Share Posted November 3, 2021 This does work for me, but I'm not 100% sure it's the best way to go... // Create an object and delete it. MCObjectHandle locus = gSDK->CreateLocus( WorldPt( 0, 0 ) ); gSDK->DeleteObject( locus ); // Check if object still exists in the drawing. VWObject obj( locus ); if ( obj.GetType() == 0 ) { // Object does not exist in the drawing anymore. } Quote Link to comment
JBenghiat Posted November 4, 2021 Share Posted November 4, 2021 I discovered that handles need to always be initialized if not immediately assigned to a return value. For example: MCObjectHandle hObject; Will not evaluate to null, nullptr, or false. You have to use: MCObjectHandle hObject = nullptr; or the equivalent class initialization. This may be obvious to most, but until I realized this, some null checks were failing. 1 Quote Link to comment
Sam Jones Posted November 4, 2021 Share Posted November 4, 2021 Scary. Do you know if this is true in the VS environment. I check for NIL handles, but have never initialized any. From what you wrote, it would seem a collection of: HandleVar := NIL; statements would be required at the beginning of every script command or contained in any initialization subroutine. Quote Link to comment
Maarten DE Posted November 4, 2021 Share Posted November 4, 2021 I don't thinkg so, I have the feeling this is dealt with by the VS API, all these scripts messages 0. PROCEDURE Test; VAR h : HANDLE; BEGIN Message(h); END; Run(Test); PROCEDURE Test; PROCEDURE Proc; VAR h : HANDLE; BEGIN Message(h); END; BEGIN Proc; END; Run(Test); PROCEDURE Test; VAR b : BOOLEAN; FUNCTION Func : BOOLEAN; VAR h : HANDLE; BEGIN Message(h); Func := false; END; BEGIN b := Func; END; Run(Test); 2 Quote Link to comment
JBenghiat Posted November 4, 2021 Share Posted November 4, 2021 I concur. The variable types in vs and python are good about self-initializing. In fact, my preferred way to check for a null handle in python is to compare to vs.Handle(0). So extra tricky for those of us crossing over to c++. 1 Quote Link to comment
Sam Jones Posted November 4, 2021 Share Posted November 4, 2021 1 minute ago, JBenghiat said: So extra tricky for those of us crossing over to c++. True, as with all things C++, but you get to drive an all terrain Corvett, and I get to drive a 10 year old Corolla. Quote Link to comment
JBenghiat Posted November 4, 2021 Share Posted November 4, 2021 1 minute ago, Sam Jones said: True, as with all things C++, but you get to drive an all terrain Corvett, and I get to drive a 10 year old Corolla. If you compare time and money spent at the repair shop… your analogy still holds 🙂 2 Quote Link to comment
Stefan Bender Posted January 20, 2022 Share Posted January 20, 2022 Handles are dangerous if you give away control to other parts of the software that could delete them. Maybe you could store the UUID of the objects instead of the handles and call virtual MCObjectHandle VCOM_CALLTYPE GetObjectByUuid(const TXString& uuid) = 0; if you need to access the object later. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.