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
    • Login

    Creating Library problem [SOLVED]

    SDK Help
    0
    27
    15.7k
    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 09/09/2014 at 14:08, xxxxxxxx wrote:

      You're welcome. 🙂
      Btw, I think to make your original example work, you were indeed doing something
      wrong with calling the pointer-to-member function.

      Especially this looks strange to me:  lib->mHook.get_value()

      I think the right code would be something like this:

      class MyHookLib : public C4DLibrary
      {
      public:
        int ( **SceneHookData** ::*get_value)() const;
      };
        
      class MyHookMirror : public BaseSceneHook
      {
      public:
        int get_value() const
        {
          SceneHookData* data = static_cast<SceneHookData*>(GetNodeData());
          MyHookLib* lib = CheckLib(...);
          if (data && lib && lib->get_value)
            return **(data- >*lib->get_value)();**
          return -1;
        }
      }
      

      Note that it's using a pointer-to-member function of a SceneHookData class as your own
      SceneHookData subclass will not be visible to users of your library (and it should work
      though!).

      See also: http://www.parashift.com/c++-faq-lite/pointers-to-members.html

      Best,
      -Niklas

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

        On 09/09/2014 at 14:55, xxxxxxxx wrote:

        Originally posted by xxxxxxxx

        You're welcome. 🙂
        Btw, I think to make your original example work, you were indeed doing something
        wrong with calling the pointer-to-member function.

        Especially this looks strange to me:  lib->mHook.get_value()

        return (data- >*lib->get_value)();

        Thanks, but that was not my code but the changed code of Mohamed. My code is the one in the initial thread posting (and does already as you suggest) 🙂

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

          On 09/09/2014 at 15:02, xxxxxxxx wrote:

          Originally posted by xxxxxxxx

          int ( SceneHookData ::*get_value)() const;

          Note that it's using a pointer-to-member function of a SceneHookData class as your own
          SceneHookData subclass will not be visible to users of your library (and it should work
          though!).

          So you are saying that when I am using (MyHook::*get_value) instead of its base class it won't work? I will read up on this link tommorrow (unbelievably tired..), but that would be a bummer. (I mean it would be great if that was the issue, I am all for anything that fixes my problem..hehe)

          My thoughts were that I can forward declare the class to use for the pointer-to-member function declaration (just as it is done with the iMy1DVector taking the SDK example as refernce). imo that should work. Really must read up on that link. This feels strange (especially as get_value is not defined in SceneHookData).. 🙂 But I'll try it out.

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

            On 09/09/2014 at 15:44, xxxxxxxx wrote:

            Originally posted by xxxxxxxx

            Originally posted by xxxxxxxx

            You're welcome. 🙂
            Btw, I think to make your original example work, you were indeed doing something
            wrong with calling the pointer-to-member function.

            Especially this looks strange to me:  lib->mHook.get_value()

            return  (data- >*lib->get_value)();

            Thanks, but that was not my code but the changed code of Mohamed. My code is the one in the initial thread posting (and does already as you suggest) 🙂

            Oh sorry, you are right 🙂 But  (((MyHook* )this)->*(lib->get_value))();  is not right either.
            this is not MyHook (SceneHookData subclass) but MyHook_mirror (BaseSceneHook subclass), it
            is therefore undefined to cast it into a MyHook pointer. 🙂

            Originally posted by xxxxxxxx

            Originally posted by xxxxxxxx

            int ( SceneHookData ::*get_value)() const;

            Note that it's using a pointer-to-member function of a SceneHookData class as your own
            SceneHookData subclass will not be visible to users of your library (and it should work
            though!).

            So you are saying that when I am using (MyHook::*get_value) instead of its base class it won't work? I will read up on this link tommorrow (unbelievably tired..), but that would be a bummer. (I mean it would be great if that was the issue, I am all for anything that fixes my problem..hehe)

            My thoughts were that I can forward declare the class to use for the pointer-to-member function declaration (just as it is done with the iMy1DVector taking the SDK example as refernce). imo that should work. Really must read up on that link. This feels strange (especially as get_value is not defined in SceneHookData).. 🙂 But I'll try it out.

            I'm not sure what you're trying to say, so I'll try to clarify what I meant: I think that you usually
            don't expose the SceneHookData subclass declaration to the third party that uses the functionality
            of your plugin provided by your C4DLibrary. The MyHook class will therefore not be defined at this
            point in the code.

            Originally posted by xxxxxxxx

            This feels strange (especially as get_value is not defined in SceneHookData)..

            The syntax is confusing. For pointer-to-member functions you have to declare the type of the
            object that you will call the function for. The part after :: does not need to be a member of
            the class, but it is the name of the declaration (variable or typedef name).

            typedef int (*some_func_t)(FooClass* );
            typedef int (FooClass::*some_member_func_t);

            some_func_t           func        = &SomeGlobalFunction;
            some_member_func_t    member_func = &FooClass::SomeFunction;

            Best,
            -Niklas

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

              On 10/09/2014 at 00:47, xxxxxxxx wrote:

              Hey Niklas!

              Originally posted by xxxxxxxx

              Oh sorry, you are right 🙂 But  (((MyHook* )this)->*(lib->get_value))();  is not right either.
              this is not MyHook (SceneHookData subclass) but MyHook_mirror (BaseSceneHook subclass), it
              is therefore undefined to cast it into a MyHook pointer. 🙂

              This should be a pointer to the class (http://www.parashift.com/c++-faq-lite/dotstar-vs-arrowstar.html).
              Hmm, then I don't understand the libs used in the C4D API (and the SDK example for creating a library is wrong then?). For example, check out lib_batchrender:

              class BatchRender
              {
              	private:
              		BatchRender();
              		~BatchRender();
              	public:
              		Bool Open(void);
              };
               
              //---------------------------------------------------
              //	---INTERNAL STUFF
               
              class iBatchRender; //Forward Declaration!
               
              struct BatchRenderLibrary : public C4DLibrary
              {
               Bool					(iBatchRender::\*Open)	  
              };
              

              Here iBatchRender is forward declared and still used for defining the according member function call. It is also not visible to the third party (me in this case 😄 ) but is simply forward declared in order to make the definition. This is the classic C++ class layering to me.

              and check out how the lib now does the library call:

              Bool BatchRender::Open()
              {
              	BatchRenderLibrary \*lib = CheckBatchRenderLib(LIBOFFSET(BatchRenderLibrary, Open));
              	if (!lib || !lib->Open) return FALSE;
              	return (((iBatchRender\* )this)->\*(lib->Open))(); 
              }  
                
              It uses iBatchRender here as well (though it's not defined).  
              To me this looks fine (as forward declared) and should still point correctly to the member function. Can you elaborate a bit more? Thanks!  
              However, I have definetly not taken into the account the GetNodeData call as you have it. This is a potential gap in my code!!  
              Thanks!  
              

              Originally posted by xxxxxxxx

              I'm not sure what you're trying to say, so I'll try to clarify what I meant: I think that you usually
              don't expose the SceneHookData subclass declaration to the third party that uses the functionality
              of your plugin provided by your C4DLibrary. The MyHook class will therefore not be defined at this
              point in the code.

              Yeah, although true, what I mean is that the definition does not need to be available at this point but only at the point when I assign the member function pointer (which happens in the internal.cpp to stay with your code example file names).
              Just like with any other forward declaration of classes, as long as I don't call member functions of the pointer (etc.), I can easily use it's declaration in my code even if the class is not yet defined). As all I need here is a pointer-to-class if you want so (since all object pointers are of same size, the compiler shouldn't care).

              The syntax is confusing. For pointer-to-member functions you have to declare the type of the
              object that you will call the function for. The part after :: does not need to be a member of
              the class, but it is the name of the declaration (variable or typedef name).

              typedef int (*some_func_t)(FooClass* );
              typedef int (FooClass::*some_member_func_t);

              some_func_t           func        = &SomeGlobalFunction;
              some_member_func_t    member_func = &FooClass::SomeFunction;

              thanks for this one, I wasn't aware of that actually (or misinterpreted that is was only a declaration name). This is still nightmare syntax and I hate C++ for it as it confuses me 😠 😂

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

                On 10/09/2014 at 01:31, xxxxxxxx wrote:

                Originally posted by xxxxxxxx

                However, I have definetly not taken into the account the GetNodeData call as you have it. This is a potential gap in my code!!
                Thanks!

                Yes, yes, yes! Thanks so much Niklas. This little thingy seems to have been the culprit!! If I change the code to   
                (((const MyHook\* )this->GetNodeData())->\*(vlib->get_value))(); 
                  
                then it works!! I now get the correct value :) Of course it then works. It was stupid of me to cast directly to the SceneHookData without using GetNodeData...sigh, I need more sleep!  
                I will change the other code of mine and see if this works for the other member functions I have as well, but you definetly deserve a beer (was trinkt man bei euch so?)! ;)  
                  
                I report back if everything works now as expected  
                
                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 10/09/2014 at 04:24, xxxxxxxx wrote:

                  Yep, now it all works like a charm. 👍 it was well worth the discussion!

                  Sigh, such a minor mistake of mine cost me 3 days...always the same with this coding 😄

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