COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :

Go Back   Cockos Incorporated Forums > Other Software Discussion > WDL users forum

Reply
 
Thread Tools Display Modes
Old 08-11-2015, 05:31 PM   #1
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default How to access my IPlugMyPlug from another class (that gets IPlugBase * pPlug)??

I'm doing a processor function to pass the audio into and it needs to see some IPlug functions.

I see that I pass an IPlugBase * pPlug as "this" (so it should be passed as IPlugMyPlug) as the first reference from the IPlugMyPlug constructor to the processor class contructor, but in the processor class constructor I can only see and access IPlugBase members and not IPlugMyPlug which is inherited from IPlugBase.

So how to have a reference to IPlugMyPlug?
mviljamaa is offline   Reply With Quote
Old 08-11-2015, 11:13 PM   #2
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 2,932
Default

Code:
IPlugMyPlug* pMyPlug = (IPlugMyPlug*)pPlug;
After that you can access all of IPlugMyPlug's methods through pMyPlug.
Tale is offline   Reply With Quote
Old 08-12-2015, 02:52 AM   #3
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

I'm seeing errors

error C2065: 'IPlugMyPlug' : undeclared identifier.
error C2059: syntax error : ')'

The line is:

IPlugMyPlug * pPlug = (IPlugGamma*)pPlug;

The header "IPlugMyPlug.h" has been included.

Is it a circular dependency if now my IPlugMyPlugControls.h includes IPlugMyPlug.h and IPlugMyPlug.h includes IPlugMyPlugControls.h?

Last edited by mviljamaa; 08-12-2015 at 04:23 AM.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 04:43 AM   #4
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 2,932
Default

Your headers should include #pragma once (or similar #ifdefs), that way they should be able to include one another.
Tale is offline   Reply With Quote
Old 08-12-2015, 04:51 AM   #5
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Quote:
Originally Posted by Tale View Post
Your headers should include #pragma once (or similar #ifdefs), that way they should be able to include one another.

They all have

#ifndef __ThisClass__
#define __ThisClass__
//Code
#endif

constructs.

Adding #pragma once to every header does not change the problem.
BTW, changing the variable name to pMyPlug and the error is given in 'pMyPlug' as well.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 05:00 AM   #6
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Ok, so it compiles if I remove the #include "IPlugMyPlug.h" from IPlugMyPlugControls.h and "replace" it by adding

class IPlugMyPlug;

to the global scope of IPlugMyPlugControls.h.

I don't understand what this does or why it works though.

The solution was described here:
http://stackoverflow.com/a/16678213/4959635

---

However, when now calling

pMyPlug->SomeFunctionOfMyPlug()

it produces

error C2027: use of undefined type 'IPlugMyPlug'
error C2227: left of '-> SomeFunctionOfMyPlug' must point to class/struct/union/generic type

Last edited by mviljamaa; 08-12-2015 at 05:06 AM.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 05:09 AM   #7
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
Ok, so it compiles if I remove the #include "IPlugMyPlug.h" from IPlugMyPlugControls.h and "replace" it by adding

class IPlugMyPlug;

to the global scope of IPlugMyPlugControls.h.

I don't understand what this does or why it works though.
It's a "forward declaration" that allows you to have pointers and references to a class in a header file, as long as you don't try using the class in any way in the header file.

You can't have value instances of a class this way, because the forward declaration can't make the compiler know even the constructors and destructors your class has. In your case just having a pointer is enough though, because you need to use the same plugin object instance anyway.

You would include the file that has the actual class declaration in your .cpp file, so you can use the class members in the cpp file.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 06:08 AM   #8
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

I guess the problem really lies in that now the both classes here require each other. The IPlugMyPlug contains a reference (protected member) to a IPanelControl that's defined in the IPlugMyPlugControls.h, whereas now IPlugMyPlugControls.h also needs to see IPlugMyPlug members.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 06:21 AM   #9
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
I guess the problem really lies in that now the both classes here require each other. The IPlugMyPlug contains a reference (protected member) to a IPanelControl that's defined in the IPlugMyPlugControls.h, whereas now IPlugMyPlugControls.h also needs to see IPlugMyPlug members.
You have to arrange things so that isn't necessary. Most probably the solution involves not having any code in your IPlugMyPlugControls.h that tries to use the IPlugMyPlug object. (That is, implement everything in IPlugMyPlugControls.cpp.)
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 06:40 AM   #10
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Design-wise I don't see how that could lead to a senseful design.

The design (for a multi-band compressor type of plug) I have is this:

MyProcessor class is a single (band-specific) DSP processor.
IPlugMyPlug is the typical IPlug class.
IPlugMyPlugControls contains the GUI.

Since IPlugMyPlug processes audio in ProcessDoubleReplacing, then it should contain a std::vector of MyProcessors (all the processors used to process the audio). Since it also draws to the GUI, then it also contains references to the IPanelControls that it passes data to.

MyProcessors read parameters from the GUI so a logical way to pass them from the GUI to the processors would again be in the IPlugMyPlug, since it contains the controls (like in all WDL-OL examples).

The particular function that I'm adding is to add processors. It's known in the IPlugMyControl, when the user has set that a new processor should be created. Since the vector holding them is in IPlugMyPlug, then the function has to be there.

I'm already passing stuff between the classes, but now it seems that this particular addition doesn't work?

Might try "polling" the GUI from the IPlugMyPlug ProcessDoubleReplacing, rather than have the GUI call IPlugMyPlug.

Last edited by mviljamaa; 08-12-2015 at 06:51 AM.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 06:52 AM   #11
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Have you at least moved all your actual code into separate .cpp files? If you haven't, that is the first step you need to do.

Having code in headers is "convenient" if you can't be bothered to create a new .cpp file, but it will eventually lead to problems.

Header-only code is mostly suitable for stuff that involves templates or simple standalone functions.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 06:53 AM   #12
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Why can it pass and access the IPlugBase (passed from IPlugMyPlug as "this"), but not IPlugMyPlug, which is inherited from IPlugBase?

All other code is laid out properly in .h/.cpp except the IPlugMyControls.h which is a single .h file. Like in WDL-OL examples (e.g. IPlugSideChain).
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 06:56 AM   #13
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
Like in WDL-OL examples.
Don't blindly trust examples...
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 06:58 AM   #14
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Wonder if it would fix if I split the IPlugMyPlugControls into .h and .cpp? Since that's how IPlugMyPlug and MyProcessor cooperate with eachother as well, with no hiccups.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 07:04 AM   #15
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
Wonder if it would fix if I split the IPlugMyPlugControls into .h and .cpp? Since that's how IPlugMyPlug and MyProcessor cooperate with eachother as well, with no hiccups.
Yes, that's what I have tried to tell you above. Forward declare your plugin class in the .h file (so you can have a pointer to the class) but do NOT include the header file that has the class. Then in the IPlugMyPlugControls .cpp you can include the header file that is needed to access the class.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 07:23 AM   #16
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Why doesn't the typical include procedure work? Why do I need to use forward declaration?
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 07:30 AM   #17
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
Why doesn't the typical include procedure work? Why do I need to use forward declaration?
Because of circular includes, C++ (which inherits this mess from C), can't deal with it otherwise. There might be some obscure other tricks, but forward declaration is the standard way to deal with this. Forward declarations (and avoiding including other header files in header files) are also often recommended to be used even if you don't have circular includes, to speed up compile times, but I have to say I've never seen any concrete benefit like that from doing it.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 07:37 AM   #18
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

So could I replace my includes in other header files with the same forward declarative procedure?
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 07:46 AM   #19
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
So could I replace my includes in other header files with the same forward declarative procedure?
Yes, for suitable stuff of course, but I don't suppose it will be worth it doing it like that if there's no immediate need.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 01:03 PM   #20
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

So turns out that doing the split broke something. The code compiles, but Reaper now hangs at the load and never displays the plug-in.

I have no idea what broke and can't revert back. Any ideas how to troubleshoot? There are not many things I changed and there are no compiler errors.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 01:09 PM   #21
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
So turns out that doing the split broke something. The code compiles, but Reaper now hangs at the load and never displays the plug-in.

I have no idea what broke and can't revert back. Any ideas how to troubleshoot? There are not many things I changed and there are no compiler errors.
Clean and rebuild everything.

Build the plugin in debug mode and run it under the debugger. (By setting Reaper.exe as the command to be executed when debugging.) Hopefully the bug will then appear in a way that the debugger will be able to catch it.

Why can't you revert back, by the way? Version control software like Git is essential to use when developing! It would allow keeping track of your progress and switch back between old and new and alternative versions of the code...
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 01:25 PM   #22
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Quote:
Originally Posted by Xenakios View Post
Clean and rebuild everything.

Build the plugin in debug mode and run it under the debugger. (By setting Reaper.exe as the command to be executed when debugging.) Hopefully the bug will then appear in a way that the debugger will be able to catch it.

Why can't you revert back, by the way? Version control software like Git is essential to use when developing! It would allow keeping track of your progress and switch back between old and new and alternative versions of the code...
Because I lost my undo history And I'm not accustomed to software development. This is like the first bigger project I'm writing.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 01:33 PM   #23
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Oh and well, you can of course set any other host to be debugged too...But Reaper is a nice host to test plugins with.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 02:45 PM   #24
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Got it working again by commenting out tons of code almost randomly.

Phew, might as well set Git or something. I don't even have backups and this project has like 2.5 months of work already.

Now to see where the problem is.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 06:45 PM   #25
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Okay so got the .h/.cpp splitting done. And I did the forward declaration and included the header as was suggested above.

I'm now seeing the plug-in crash at startup when I've added a call to the IPlugMyPlug::AddProcessor() function from the IPlugMyPlugControls.cpp (that is, it's called when the user has requested a processor to be created using the GUI). It's not the call to the function itself that causes a crash, but when in the call body I do

processors.push_back(new MyPlugProcessor());

Where processors is a std::vector<MyPlugProcessor*> and a private member in the IPlugMyPlug.h file.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 07:00 PM   #26
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
Okay so got the .h/.cpp splitting done. And I did the forward declaration and included the header as was suggested above.

I'm now seeing the plug-in crash at startup when I've added a call to the IPlugMyPlug::AddProcessor() function from the IPlugMyPlugControls.cpp (that is, it's called when the user has requested a processor to be created using the GUI). It's not the call to the function itself that causes a crash, but when in the call body I do

processors.push_back(new MyPlugProcessor());

Where processors is a std::vector<MyPlugProcessor*> and a private member in the IPlugMyPlug.h file.
It's possible the memory allocation of "new" fails (fairly unlikely) or the constructor of MyPlugProcessor does something nasty.

Additionally it's possible your processor vector is accessed simultaneously from another thread, so you shouldn't do the push_back without synchronization (basically mutex locking in IPlug context) of the threads.

You moving the code to the .cpp file likely has nothing to do with this directly, some problem just started manifesting itself at the same time.

Your project now seems complicated enough that it is very hard to anymore understand what you are doing and help you effectively. Have you considered posting the source code online, so it could be more quickly reviewed when you need some help with it?
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 07:04 PM   #27
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

Could it be the #include guards or #pragma once in the MyPlugProcessor class files? Don't they block multiple instantiation?
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 07:10 PM   #28
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
Could it be the #include guards or #pragma once in the MyPlugProcessor class files? Don't they block multiple instantiation?
Those have nothing to do with runtime issues, include guards are needed to compile to code properly...
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 07:11 PM   #29
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

It's not the new MyPlugProcessor() that crashes. But pushing it back to the vector.
mviljamaa is offline   Reply With Quote
Old 08-12-2015, 07:13 PM   #30
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,673
Default

Quote:
Originally Posted by mviljamaa View Post
It's not the new MyPlugProcessor() that crashes. But pushing it back to the vector.
Threading issue then probably...
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is offline   Reply With Quote
Old 08-12-2015, 07:40 PM   #31
mviljamaa
Human being with feelings
 
Join Date: Jun 2015
Posts: 348
Default

And I've not had an intro to the threading in WDL-OL yet. I had the other threading problem with passing the STFT to the GUI class.
mviljamaa is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 11:08 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.