Sharing BaseArrays between plugins [SOLVED]



  • On 01/07/2016 at 09:38, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   14+ 
    Platform:   Windows  ; Mac  ;  Mac OSX  ; 
    Language(s) :     C++  ;

    ---------
    Hi,

    I was wondering what would be the best way to share class level BaseArray variables between different plugins.

    For example, PluginA has a BaseArray vector list called vectorsA, and PluginB has a vector list called vectorsB. How can I have PluginA read vectorsB?

    I am working with generator objects and both vectorsA and vectorsB lists are procedurally generated.

    Any help would be greatly appreciated as always.



  • On 02/07/2016 at 05:40, xxxxxxxx wrote:

    Howdy,

    Well, there are a few different ways to do that. First of all you need to make the array public, and then create a public accessor function in the class that returns a pointer to the array.

    If the two plugins are in the same dynamic library, then each plugin's code can simply include the other's header file (assuming you have the class defined in a separate header file).

    If each plugin is in a different dynamic library, then you can create external and internal accessor functions, and include the external accessor functions in each plugin. Read the "Creating Libraries" section in any one of the pre R16 SDK's documentation for more information on internal/external accessor functions. That section seems to have gotten lost in the newer documentation style, or at least I can't find it anymore.

    Adios,
    Cactus Dan



  • On 02/07/2016 at 11:47, xxxxxxxx wrote:

    Thanks for the reply Dan.

    I already did that. What I am struggling with is how to access the (public) functions of the other plugin.

    What I am doing is getting pluginB as a link BaseObject into pluginA.
    Once I do that, how do I access its functions?

    BaseObject* pluginBObject = bc->GetObjectLink(PLUGINB_LINK,doc);
    

    Now I have pluginB as a BaseObject inside pluginA. How do I now access pluginB public functions?

    Both plugin A and B reside in the same dll.



  • On 02/07/2016 at 15:10, xxxxxxxx wrote:

    You can cast the result of pluginBObject->GetNodeData() to your Plugin B class. Note that this does not work out of the box if the plugins reside in different dynamic libraries (as Cactus Dan mentioned).

    I can also reccommend using messages.

    MyMessageData data;
    pluginBObject->Message(MY_MESSAGE_ID, &data);
    // read values that were filled into "data"
    

    This also works with the plugins in different libraries.

    Best,
    Niklas



  • On 02/07/2016 at 16:28, xxxxxxxx wrote:

    Howdy,

    Originally posted by xxxxxxxx

    Thanks for the reply Dan.

    I already did that. What I am struggling with is how to access the (public) functions of the other plugin.

    What I am doing is getting pluginB as a link BaseObject into pluginA.
    Once I do that, how do I access its functions?

    BaseObject* pluginBObject = bc->GetObjectLink(PLUGINB_LINK,doc);
    

    Now I have pluginB as a BaseObject inside pluginA. How do I now access pluginB public functions?

    Both plugin A and B reside in the same dll.

    Well, you could do this in your class definition:

    Class PluginObjectB : public ObjectData
    {
    public:
    	BaseArray *arrayB;
    	
    	BaseArray* GetArrayPointer(void) { return arrayB; }
      
    	// rest of class functions
    };
    

    ... and then call it like this:

    BaseObject* pluginBObject = bc->GetObjectLink(PLUGINB_LINK,doc);
    PluginObjectB *objB = static_cast<PluginObjectB*>(pluginBObject->GetNodeData());
    BaseArray *arrB = objB->GetArrayPointer();
    

    EDIT :
    Actually it would be safer to call the accessor function like this:

    BaseArray *arrB = objB ? objB->GetArrayPointer() : NULL;
    

    ... just in case the casting fails

    Adios,
    Cactus Dan



  • On 02/07/2016 at 22:01, xxxxxxxx wrote:

    Thanks Dan and Niklas for the help.

    I got it to work with casting.

    PluginObjectB *objB = static_cast<PluginObjectB*>(pluginBObject->GetNodeData());
    

    It turns out this was all that's needed to access any public members from pluginB without even using any extra pointer functions.



  • On 04/07/2016 at 06:58, xxxxxxxx wrote:

    Hey,

    nice discussion you had in here. And thanks to Niklas and Dan for helping us in our job, very much appreciated! 🙂

    I just want to add a few links into our new documentation:
    Another way not yet discussed in here would be to use MSG_RETRIEVEPRIVATEDATA.
    And then on casting of NodeData (please note, the syntax changed with R17 and the actual cast is done internally).



  • On 04/07/2016 at 09:15, xxxxxxxx wrote:

    Howdy,

    OH, yes. Thanks Andreas for pointing that out. I keep forgeting to use my compatibility wrapper function template instead of GetNodeData() for my new code. I'll need to go back through all my plugins and fix the new code. Otherwise, I wouldn't find out until I compiled the R17 versions (which I end up doing last). 😉

    Adios,
    Cactus Dan


Log in to reply