Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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
    • Login

    BaseArray in Struct, how to manage [SOLVED]

    SDK Help
    0
    7
    737
    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.
    • H
      Helper
      last edited by

      On 29/04/2017 at 10:42, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:    
      Platform:      
      Language(s) :     C++  ;

      ---------
      Hi I would like to have an BaseArray into a struct. But I didn't succes to fill it after.
      Here is a sample code without error checking.

      typedef struct iobject{
          String name;
          maxon::BaseArray<Int32> uvCount;
      };
        
      iobject* objectData = new iobject();
        
      //don't work
      objectData->uvCount.Append(42);
        
        
      //don't work either
      maxon::BaseArray<String> buffer = objectData->uvCount;
      buffer.Append(42)
      objectData->uvCount = buffer;
        
      //seem to work but why other doesn't?
      objectData->uvCount.Insert(objectData->uvCount.End, 42);
      

      Thanks in advance

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 02/05/2017 at 13:21, xxxxxxxx wrote:

        Hi gr4ph0s, thanks for writing us.

        Unfortunately, as far as I tried to, I'm unable to replicate your issue under Mac or under Window.
        Although my tests have been successful either using new or NewObj() I warmly suggest to use the last one in order to optimise memory allocation and memory management under Cinema 4D. In order to get an overall overview on the topic have a look at the Entity Creation and Destruction Manual in Cinema API documentation

        Additionally I don't get what's the real intent of the code following the comment "//don't work either" which to me looks pretty odd.

        Last but not least beware of deallocating the newly created object to avoid memory leaks: depending on the fact that you decided to use "new" or "NewObj()" use respectively "delete" or "DeleteObj()" to free the allocated resources.

            typedef struct iobject
            {
                String mystring;
                maxon::BaseArray<Int32> mybasearray;
            } DUMMYTYPE;
            
            // instantiate a new object
            DUMMYTYPE* objDummyType = new DUMMYTYPE();
            
            // check the existence of new object
            if (!objDummyType)
                return false;
            
            // append some values
            objDummyType->mybasearray.Append(-1);
            objDummyType->mybasearray.Append(-10);
            objDummyType->mybasearray.Append(-100);
            
            // check the stored values
            for (Int32 i = 0; i < objDummyType->mybasearray.GetCount(); ++i)
            {
                GePrint("objDummyType->mybasearray[" + String::IntToString(i) + "]: " + String::IntToString(objDummyType->mybasearray[i]));
            }
            
            // deallocate the instance
            delete (objTypeA);
        

        Best, Riccardo

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 02/05/2017 at 15:00, xxxxxxxx wrote:

          Thanks for taking time to answerd me.

          Yeah about the string was just a bad copy/cat from myself.

          I guess my error is how I handled struct. But anyway I figured out and with your example I understand why !

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 04/05/2017 at 04:54, xxxxxxxx wrote:

            Sorry for the double post but I guess it's the only way for bumping it.
            In this case how to handle thing properly?

            struct MyStructB{
                maxon::BaseArray<Int32> ArrayOfInt;
                };
              
            struct MyStructA{
                maxon::BaseArray<MyStructB> ArrayOfIntArray;
                };
              
            AutoNew<MyStructA> myVar;
            

            What must be my constructor for MyStructB?
            Coz I always got error C2248 while nothing is declarated as private.
            So I guess it's the BaseArray who got some parameters marked as private.
            Error 10 error C2248: 'maxon::BaseArray<Bool,0x010,BASEARRAYFLAGS_0,maxon::DefaultAllocator>::BaseArray' : cannot access private member declared in class 'maxon::BaseArray<Bool,0x010,BASEARRAYFLAGS_0,maxon::DefaultAllocator>'

            So far the only solution I found was to convert ArrayOfInt into vector instead of BaseArray. But I would like to use maxon api since STL is not recommended.

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 04/05/2017 at 08:42, xxxxxxxx wrote:

              Hi gr4ph0s, first thanks for keeping asking.

              With reference to your question, I suggest you to have a look inside the basearray.h at the BaseArray template definition. There you'll find a MAXON_DISALLOW_COPY_AND_ASSIGN preprocessor directive which basically prevents copying the class specified (in our case the BaseArray itself).

              Because of this directive you're provided by the compiler with the C2248 error you've reported. Basically when you try to store a new instance of MyStructB into the ArrayOfIntArray pointed by myVar the directive prevents your instance to get copied and assigned to the appended entry of the ArrayOfIntArray.

              In order to make everything working smoothly, you have to store pointers to MyStructB in the BaseArray in MyStructA and operate accordingly

                      struct MyStructB{  
                        maxon::BaseArray<Int32> ArrayOfInt;  
                    };
                
                      struct MyStructA{  
                        maxon::BaseArray<MyStructB*> ArrayOfIntArray;  
                    };
                
                      // auto-allocate an instance of MyStructA  
                    AutoNew<MyStructA> arrStructB;
                
                      // check the pointer of the allocated instance  
                    if (!arrStructB)  
                        return;
                
                      // append an pointer going to point to a 'soon-to-be-allocated' MyStructB  
                    arrStructB->ArrayOfIntArray.Append();
                
                    // allocate the MyStructB instance and save the memory location in the pointer  
                    arrStructB->ArrayOfIntArray[0] = NewObjClear(MyStructB);
                
                    if (arrStructB->ArrayOfIntArray[0])  
                    {  
                        // fill the newly created instance of MyStructB  
                        arrStructB->ArrayOfIntArray[0]->ArrayOfInt.Append(1);  
                        arrStructB->ArrayOfIntArray[0]->ArrayOfInt.Append(10);  
                        arrStructB->ArrayOfIntArray[0]->ArrayOfInt.Append(100);  
                    }
                
                      // append another pointer going to be point to another MyStructB  
                    arrStructB->ArrayOfIntArray.Append();
                
                    // allocate the MyStructB instance and save the memory location in the pointer  
                    arrStructB->ArrayOfIntArray[1] = NewObjClear(MyStructB);
                
                    if (arrStructB->ArrayOfIntArray[1])  
                    {  
                        // fill the newly created instance of MyStructB  
                        arrStructB->ArrayOfIntArray[1]->ArrayOfInt.Append(2);  
                        arrStructB->ArrayOfIntArray[1]->ArrayOfInt.Append(20);  
                        arrStructB->ArrayOfIntArray[1]->ArrayOfInt.Append(200);  
                    }
                
                      // check that everything is properly stored  
                    for (int i = 0; i < arrStructB->ArrayOfIntArray.GetCount(); ++i)  
                    {  
                        MyStructB* pMyStructB = arrStructB->ArrayOfIntArray[i];  
                        for (int j = 0; j < pMyStructB->ArrayOfInt.GetCount(); ++j)  
                        {  
                            Int32 value = pMyStructB->ArrayOfInt[j];  
                            GePrint("[" + String::IntToString(i) + "," + String::IntToString(j) + "]: " + String::IntToString(value));  
                        }  
                    }
                
                      // deallocate each instance pointed by the pointers stored in the MyStructA instance  
                    for (int i = 0; i < arrStructB->ArrayOfIntArray.GetCount(); ++i)  
                    {  
                        DeleteObj(arrStructB->ArrayOfIntArray[i]);  
                    }
              

              Best, Riccardo

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 04/05/2017 at 10:09, xxxxxxxx wrote:

                Thanks you a lot riccardo for taking time to answerd me.

                Btw NewObjClear is just for allocating memory while NewObj allocate the objet. Isn't it?

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 16/05/2017 at 06:50, xxxxxxxx wrote:

                  Hi gr4ph0s,

                  the former allocates the memory block hosting the object instance and clear it while  the second just allocates the memory block.

                  Best, Riccardo

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