Missing JUCE_API


#1

Hi,

I’m using Visual Studio 2008 SP1 on Windows 7 Pro SP1 64.
I’ve just switching my project to link Juce dynamically.
Everything was going fine except some link errors because some part of Juce was not exported.

My project create some instances of Juce public nested classes like
class Image::BitmapData, or struct CodeEditorComponent::ColourScheme.

My project also uses some Juce global functions like
OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, xxx);

If I add JUCE_API keyword to all of this definitions, linkage succeed.

Visual Studio also complains about some exposed Juce classes who inherit from unexposed Juce classes
warning C4275: non dll-interface class ‘BaseClass’ used as base for dll-interface class ‘ChildClass’

BaseClass can be class TextEditor::InputFilter, class TextEditor::Listener and class Slider::Listener.

adding JUCE_API keyword to those base classes definitions makes this warning disappear.

Do you think this change can be integrated to Juce ?

Thanks in advance.


#2

Thanks! I try to remember to add the JUCE_API thing to all the necessary classes, but often forget because I never do any DLL builds myself. Just let me know any classes where it’s missing and I’ll update it…


#3

OK, I will report Visual Studio’s errors about this issue.

After your last fix, it remains some JUCE_API missing:

in juce_OuputStream.h
Before each operator<< OutputStream functions.

in juce_TextEditor.h
for class TextEditor::Listener

in juce_Slider.h
for class Slider::Listener

There are probably more of them, but my project didn’t link with them yet.

Thanks in advance for those ones.


#4

Ok, try again now…


#5

Outch

I’ve some building error because we need to switch order of __declspec and calling convention of JUCE_CALLTYPE and JUCE_CDECL macro.
According to the following msdn syntax:
http://msdn.microsoft.com/en-us/library/49147z04(v=vs.71).aspx
declspec should be after the return type and before an optional calling convention.

I also have some error because some functions use two macros (JUCE_API and JUCE_CALLTYPE) (decl_spec was defined twice).

JUCE_API String JUCE_CALLTYPE operator+ (const char* string1, const String& string2);


#6

Sorry - have made another attempt now…


#7

Now it’s working perfectly
Thanks.


#8

Hi !

It seems that JUCE_API is missing on class JSON’s definition
in /modules/juce_core/json/juce_JSON.h file.

Thanks in advance for this change.


#9

Hi,

When Juce is built as a DLL, juce_Memory.h overload the JUCE_LEAK_DETECTOR to avoid cross binary new/delete problems.
In this case, the leak detector do not work anymore.

In my case, all EXE/DLLs are build with the same compiler with same compiling options.
(so they link with the same CRT version and use the same heap)

I would like to benefit the leak detector in this case.
Could you provide a compiler defined option allowing to enable or disable the usage of the default JUCE_LEAK_DETECTOR behavior when Juce was build as a DLL

Thanks in advance for your concern about this feature.


#10

If you set the JUCE_LEAK_DETECTOR macro to 1 or 0 in your project settings or app header, then it won’t override your setting.


#11

I think that If I set JUCE_LEAK_DETECTOR to 0 or 1, implementation in juce_LeakedObjectDetector.h will be also disabled.
When I build juce as a DLL, I would like to use the juce_LeakedObjectDetector.h implementation of JUCE_LEAK_DETECTOR instead of the juce_Memory.h implementation of JUCE_LEAK_DETECTOR.

Just to clarify my point, I would like juce classes use leak detector when I’m building juce as a DLL.
In others DLL, I also use the juce leak detector for my own classes.

Actually, my solution is to comment the JUCE_LEAK_DETECTOR definition of juce_Memory.h
It’s not very pretty.

Do you suggest to copy past JUCE_LEAK_DETECTOR implementation of juce_LeakedObjectDetector.h in my own app header ?


#12

Yes, you could do that. Or if you want to suggest a modification to the library that’d do what you need, then fire away.


#13

To be consistent with Juce philosophy I would like to write something like that:

Defining a new JUCE_CHECK_DLL_MEMORY_LEAKS macro set to 0 to do not modify the current default behavior, by adding this code block in juce_core.h

[code]//=============================================================================
/** Config: JUCE_CHECK_DLL_MEMORY_LEAKS

Enables a memory-leak check for certain objects when the app terminates. See the LeakedObjectDetector
class and the JUCE_LEAK_DETECTOR macro for more details about enabling leak checking for specific classes.

*/
#if JUCE_MSVC && (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD)) && ! defined (JUCE_CHECK_DLL_MEMORY_LEAKS)
#define JUCE_CHECK_DLL_MEMORY_LEAKS 0
#endif[/code]

Modifying the #if condition of juce_Memory.h JUCE_LEAK_DETECTOR definition like this:

#if JUCE_MSVC && (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD)) && ! JUCE_CHECK_DLL_MEMORY_LEAKS && ! DOXYGEN extern JUCE_API void* juceDLL_malloc (size_t); extern JUCE_API void juceDLL_free (void*); #define JUCE_LEAK_DETECTOR(OwnerClass) public:\ static void* operator new (size_t sz) { return juce::juceDLL_malloc (sz); } \ static void* operator new (size_t, void* p) { return p; } \ static void operator delete (void* p) { juce::juceDLL_free (p); } \ static void operator delete (void*, void*) {} #endif

and finally in my own app header, I should just have to write

Another suggestion is to set a new macro like JUCE_CROSS_DLL_ALLOCATION_GUARD and reverse the #if condition.


#14

Thanks. I’ll put a flag like that in there to allow the guard to be disabled, but don’t think it’s worth adding as a module setting.


#15

Thanks for this !


#16

Hi,
Another point concerning Juce DLL build with leak detector.

If I’m not wrong, because of template classes code is expanded in each dll using them,
template classes cannot use __declspec( dllimport / dllexport ) neither static leak detector mecanism.
That’s why, juce::Point, juce::Rectangle … do not uses them.

However juce::BorderSize uses JUCE_LEAK_DETECTOR.
This throw an assert when i call the following snippet

(Now, I’m using Visual Studio 2010 SP1 on Windows 7 Pro SP1 64.)

I think JUCE_LEAK_DETECTOR must be avoided in all template class of a dll.

Thanks in advance for your concern about this issue.


#17

Good point - and in fact it’s not needed in BorderSize anyway, since that class will (or should!) never be allocated on the heap.


#18

OK, thanks for this.


#19

Hi,

I updated the last version of Juce.
And I experiencing the same JUCE_LEAK_DETECTOR problem previously meet on this thread.
But this time concerning RectangleList class, who is now a template.
The following code snippet throws a bad leak detection when Juce is linked as a DLL:

const RectangleList<int> rectangleList = Desktop::getInstance().getDisplays().getRectangleList(true);

I resolve this issue by removing JUCE_LEAK_DETECTOR from RectangleList template, like we have done before for BorderSize template.

Thanks in advance for your next commit.

 

 

 


#20

Yeah, fair point, there's no real reason for RectangleList to have a leak detector, I doubt if many people would create those things on the heap (I hope not, anyway!)