Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Login

    Toolplugin Crash When Close Cinema 4D

    Cinema 4D SDK
    c++ r20
    3
    8
    1.4k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      mike
      last edited by mike

      hi,
      i write a toolplugin, alloc a baseobject in InitTool() ,the baseobject pointer is toolplugin private member. free baseobject in FreeTool .
      it works fine when switch tool .but when i close cinema 4d, myplugin will be crash and show this crash.PNG ,
      i thought maybe cinema 4d free all object auto when close(i know it will not case crash,but just try)? so i use "if(myobject != nullptr)"check if free baseobject,but it unuseful, crash again. Where did I go wrong?
      hope your help!

      class mytool : public ToolData
      {
         ......
      private:
        BaseObject* myobject;
      }
      
      Bool mytool::InitTool(BaseDocument * doc, BaseContainer & data, BaseThread * bt)
      {
        this->myobject = BaseObject::Alloc(Onull);
        doc->InsertObject(myobject,  nullptr,  false);
        return true;
      }
      
      void mytool::FreeTool(BaseDocument * doc, BaseContainer & data)
      {
         BaseObject::Free(myobject);
      }
      
      1 Reply Last reply Reply Quote 0
      • C4DSC
        C4DS
        last edited by

        From the docs:

        void InsertObject 	( 	BaseObject *  	op,
        		BaseObject *  	parent,
        		BaseObject *  	pred,
        		Bool  	checknames = false 
        	)
        
        Parameters
            [in]	op The object to insert into the document. The document takes over the ownership of the pointed object.
        

        Which means, once you have inserted the object, you should not free it! The document will do so, when being destroyed.

        M 1 Reply Last reply Reply Quote 0
        • M
          mike @C4DS
          last edited by

          @C4DS thank you for your answer.follow your answer, i think if i can detect currect project close, the problem will be solve, could your tell me how to detect currect project close in toolplugin or scenehook? hope your help : )

          1 Reply Last reply Reply Quote 0
          • M
            mike
            last edited by

            unsafe way , just use "try catch(...)",skip error, if any better solution?

            1 Reply Last reply Reply Quote 0
            • C4DSC
              C4DS
              last edited by

              DO NOT try to solve your problems by fixing the side effects.
              DO solve your problem by removing the cause.

              M 1 Reply Last reply Reply Quote 0
              • M
                mike @C4DS
                last edited by

                @C4DS maybe use scenehook detect tool switch, and trigger tool "messgae" to free mybaseobject is a better way ?it can avoid the crash,and tool also work normally

                1 Reply Last reply Reply Quote 0
                • r_giganteR
                  r_gigante
                  last edited by

                  Hi mike, thanks for reaching out us.

                  With regard to your code, there's an ownership issue: actually once you insert an object in the document, Cinema 4D takes ownership on the object and if you want to destroy it you need first to take ownership back (in this case with the BaseObject::Remove() method)

                  On top of this, in your ToolData::InitTool() method, the BaseObject::InsertObject() method is provided with a wrong sequence of parameters.

                  I suggest you to consider something like:

                  Bool PC_11560_ToolData::InitTool(BaseDocument * doc, BaseContainer & data, BaseThread * bt)
                  {
                  	// just check the passed params
                  	if (!doc || !bt)
                  		return false;
                  	
                  	// allocate and check for validity
                  	myobject = BaseObject::Alloc(Onull);
                  	if (!myobject)
                  		return false;
                  	
                  	// insert object in the document
                  	doc->InsertObject(myobject,  nullptr,  nullptr, false);
                  	return true;
                  }
                  
                  void PC_11560_ToolData::FreeTool(BaseDocument * doc, BaseContainer & data)
                  {
                  	// check the pointer validity and take back ownership by removing from the document
                  	if (myobject)
                  		myobject->Remove();
                  	
                  	// dispose the object and free the memory
                  	BaseObject::Free(myobject);
                  	myobject = nullptr;
                  }
                  

                  Finally if you want to insert an object upon user interaction there I recommend a simpler CommandData and if you need to store a reference please make proper use of BaseLink (I leave it to you)

                  Regard, Riccardo

                  M 1 Reply Last reply Reply Quote 2
                  • M
                    mike @r_gigante
                    last edited by

                    @r_gigante Thank you for your answer! it s all fine : )

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post