Juce as DLL

Hi all,
I am having trouble building juce as a DLL on windows. I get LNK2019
errors. I tried versions 1.33 and 1.29. Can any one tell me, how to build juce
as a DLL?

Thanks,
Yogesh Kini

I build it here as a dll in vcexpress and it works fine. What compiler are you using?

I am using VC++ 7.1 .net.

Ok - but what are the actual link errors? Did you define JUCE_DLL before including juce.h?

Hi,

I get the errors when I try to compile JUCE.
I changed configuration type to dll in project settings and
Rumtime Library to “MultiThreaded DLL” from “Multithreaded debug”

Should I declare JUCE_DLL in juce.h or something?

I get the following errors:

error LNK2019: unresolved external symbol __imp__midiInGetDevCapsW@12 referenced in function “public: static class juce::StringArray const __cdecl juce::MidiInput::getDevices(void)” (?getDevices@MidiInput@juce@@SA?BVStringArray@2@XZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInGetNumDevs@0 referenced in function “public: static class juce::StringArray const __cdecl juce::MidiInput::getDevices(void)” (?getDevices@MidiInput@juce@@SA?BVStringArray@2@XZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInOpen@20 referenced in function “public: static class juce::MidiInput * __cdecl juce::MidiInput::openDevice(int,class juce::MidiInputCallback *)” (?openDevice@MidiInput@juce@@SAPAV12@HPAVMidiInputCallback@2@@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInUnprepareHeader@12 referenced in function “public: virtual void __thiscall juce::MidiInThread::run(void)” (?run@MidiInThread@juce@@UAEXXZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInAddBuffer@12 referenced in function “public: void __thiscall juce::MidiInThread::writeBlock(int)” (?writeBlock@MidiInThread@juce@@QAEXH@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInPrepareHeader@12 referenced in function “public: void __thiscall juce::MidiInThread::writeBlock(int)” (?writeBlock@MidiInThread@juce@@QAEXH@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInClose@4 referenced in function “public: virtual __thiscall juce::MidiInThread::~MidiInThread(void)” (??1MidiInThread@juce@@UAE@XZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInStop@4 referenced in function “public: void __thiscall juce::MidiInThread::stop(void)” (?stop@MidiInThread@juce@@QAEXXZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInReset@4 referenced in function “public: void __thiscall juce::MidiInThread::stop(void)” (?stop@MidiInThread@juce@@QAEXXZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiInStart@4 referenced in function “public: void __thiscall juce::MidiInThread::start(void)” (?start@MidiInThread@juce@@QAEXXZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutGetDevCapsW@12 referenced in function “public: static class juce::StringArray const __cdecl juce::MidiOutput::getDevices(void)” (?getDevices@MidiOutput@juce@@SA?BVStringArray@2@XZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutGetNumDevs@0 referenced in function “public: static class juce::StringArray const __cdecl juce::MidiOutput::getDevices(void)” (?getDevices@MidiOutput@juce@@SA?BVStringArray@2@XZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutOpen@20 referenced in function “public: static class juce::MidiOutput * __cdecl juce::MidiOutput::openDevice(int)” (?openDevice@MidiOutput@juce@@SAPAV12@H@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutClose@4 referenced in function “public: __thiscall juce::MidiOutput::~MidiOutput(void)” (??1MidiOutput@juce@@QAE@XZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutReset@4 referenced in function “public: void __thiscall juce::MidiOutput::reset(void)” (?reset@MidiOutput@juce@@QAEXXZ)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutGetVolume@8 referenced in function “public: bool __thiscall juce::MidiOutput::getVolume(float &,float &)” (?getVolume@MidiOutput@juce@@QAE_NAAM0@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutSetVolume@8 referenced in function “public: void __thiscall juce::MidiOutput::setVolume(float,float)” (?setVolume@MidiOutput@juce@@QAEXMM@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutShortMsg@8 referenced in function “public: void __thiscall juce::MidiOutput::sendMessageNow(class juce::MidiMessage const &)” (?sendMessageNow@MidiOutput@juce@@QAEXABVMidiMessage@2@@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutUnprepareHeader@12 referenced in function “public: void __thiscall juce::MidiOutput::sendMessageNow(class juce::MidiMessage const &)” (?sendMessageNow@MidiOutput@juce@@QAEXABVMidiMessage@2@@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutLongMsg@12 referenced in function “public: void __thiscall juce::MidiOutput::sendMessageNow(class juce::MidiMessage const &)” (?sendMessageNow@MidiOutput@juce@@QAEXABVMidiMessage@2@@Z)
juce_win32_Midi.obj : error LNK2019: unresolved external symbol __imp__midiOutPrepareHeader@12 referenced in function “public: void __thiscall juce::MidiOutput::sendMessageNow(class juce::MidiMessage const &)” (?sendMessageNow@MidiOutput@juce@@QAEXABVMidiMessage@2@@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__InternetGetConnectedState@8 referenced in function “bool __cdecl juce::juce_isOnLine(void)” (?juce_isOnLine@juce@@YA_NXZ)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__InternetCloseHandle@4 referenced in function “void * __cdecl juce::juce_openInternetFile(class juce::String const &,class juce::String const &,bool)” (?juce_openInternetFile@juce@@YAPAXABVString@1@0_N@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__HttpSendRequestA@20 referenced in function “void * __cdecl juce::juce_openInternetFile(class juce::String const &,class juce::String const &,bool)” (?juce_openInternetFile@juce@@YAPAXABVString@1@0_N@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__HttpOpenRequestA@32 referenced in function “void * __cdecl juce::juce_openInternetFile(class juce::String const &,class juce::String const &,bool)” (?juce_openInternetFile@juce@@YAPAXABVString@1@0_N@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__FtpOpenFileA@20 referenced in function “void * __cdecl juce::juce_openInternetFile(class juce::String const &,class juce::String const &,bool)” (?juce_openInternetFile@juce@@YAPAXABVString@1@0_N@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__InternetConnectA@32 referenced in function “void * __cdecl juce::juce_openInternetFile(class juce::String const &,class juce::String const &,bool)” (?juce_openInternetFile@juce@@YAPAXABVString@1@0_N@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__InternetCrackUrlA@16 referenced in function “void * __cdecl juce::juce_openInternetFile(class juce::String const &,class juce::String const &,bool)” (?juce_openInternetFile@juce@@YAPAXABVString@1@0_N@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__InternetOpenA@20 referenced in function “void * __cdecl juce::juce_openInternetFile(class juce::String const &,class juce::String const &,bool)” (?juce_openInternetFile@juce@@YAPAXABVString@1@0_N@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__InternetReadFile@16 referenced in function “int __cdecl juce::juce_readFromInternetFile(void *,void *,int)” (?juce_readFromInternetFile@juce@@YAHPAX0H@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol __imp__InternetSetFilePointer@20 referenced in function "int _cdecl juce::juce_seekInInternetFile(void *,int)" (?juce_seekInInternetFile@juce@@YAHPAXH@Z)
juce_win32_Network.obj : error LNK2019: unresolved external symbol imp__HttpQueryInfoA@20 referenced in function "int cdecl juce::juce_getStatusCodeFor(void *)" (?juce_getStatusCodeFor@juce@@YAHPAX@Z)
juce_win32_SystemStats.obj : error LNK2019: unresolved external symbol imp__timeBeginPeriod@4 referenced in function "public: static void cdecl juce::SystemStats::initialiseStats(void)" (?initialiseStats@SystemStats@juce@@SAXXZ)
juce_win32_Windowing.obj : error LNK2019: unresolved external symbol DrawDibDraw@52 referenced in function "public: void thiscall juce::WindowsBitmapImage::blitToWindow(struct HWND *,struct HDC
*,bool,int,int,class juce::RectangleList const &)" (?blitToWindow@WindowsBitmapImage@juce@@QAEXPAUHWND
@@PAUHDC
@@NHHABVRectangleList@2@@Z)
juce_win32_Windowing.obj : error LNK2019: unresolved external symbol DrawDibOpen@0 referenced in function "public: void thiscall juce::WindowsBitmapImage::blitToWindow(struct HWND *,struct HDC
*,bool,int,int,class juce::RectangleList const &)" (?blitToWindow@WindowsBitmapImage@juce@@QAEXPAUHWND
@@PAUHDC
@@_NHHABVRectangleList@2@@Z)

Regards
Yogesh

Hi,
I managed to get dll built. I had to link to the
kernel32.lib
user32.lib and so on…
using the project settings of the JUCE solution file.

Also in juce_StandardHeader.h file, “juce_PlatformDefs.h” must
be included before the places where you use the JUCE_WIN32.
coz JUCE_WIN32 is defined in platformdefs.h.

Also I tried to build juce demo using the DLL, I built. It
does not work. It may be because all classes are not exported
to dll. Eg Colours.

Please let me know if I am doing any thing wrong.

Regards
Yogesh

no… There’s already a juce DLL configuration, you don’t need to change any settings in the juce project itself! Just build the “Debug DLL” and “Release DLL” configurations! Then in your app, define JUCE_DLL before it includes juce.h

Hi,
I am using VC++ 7.1 What I do is, upgrade the vc6.0 project file.
I do not get the “Debug DLL” and “Release DLL” configurations.

Also have you tried linking the dll, so built with juce demo?

Please help.
Yogesh

Ah - I thought there were vc6 projects for that as well, but it seems they’re only in the vcexpress version.

I think it should all work though, as long as you define JUCE_BUILD_DLL globally for the project when you build the dll.

(or just use vcexpress to build the DLLs, of course…)

… if you don’t have vcexpress, just change the vcexpress workspace and project files like described here

VCExpress is a huge hassle to setup, and it does not allow plugins like Visual Assist. So it is completely and utterly useless (Visual Studio itself is not at all pleasent to work in without Visual Assist after all :slight_smile: ).

What is the point of having a vcexpress version since any version after 6 can pull in and upgrade from a 6 project version?

You may also think about that one make manager (don’t recall the name, I can find it if need-be) that outputs project’s of many things, from near any version of VS to gcc to whatnot…

yes, we use CMake, it just works and is used in many big and complex projects.
We even integrated Juce and its dependancies in the build process on the three platforms.

There is another one called SCons but it looks much less mature.

beside, I tried visual assist before, the only useful features are now in vcexpress and in a much better and faster way… it’s never been lighter and simplier. And most of all, it has finally a decently c++ standard conformant compiler.

Hi all,
Thanks for the tip, to convert the vcexpress project.
But my initial question remains the same. Has anybody tried using
juce as dll and building the juce demo with it?

I get linker error when I do that. Because all classes are not exported to dll. Ex. SliderListener, AudioDeviceSelectorComponent and some more

Also to create JUCE_debug.lib I have to change “juce_standardHeaders.h”.
Because JUCE_API is never defined to __declspec (dllexport).

When I fix the above problems things go fine :smiley:
Jules, can you please look into it.

Thanks,
Yogesh Kini

Ah, sorry, when I add new classes I keep forgetting to make sure they’re set up for use in a DLL - sorry! It’s easy though - all you have to do is to add JUCE_API in the class declaration if you find one that I’ve missed out.

VC2k5 does not at all support all of VA’s things, it did add a couple, but even looking at basic things, VC2k5’s intellisense get’s hung up and bloated too easily, just turn it off and use VA’s instead, far better, just for that even. Not to mention I like my full setup of quick-code pastes and other such things I use often that are not in VC/any_version.

Hi Jules,
I was able to build the juce dll as you told me.I compiled the juce demo and used the dll instead of static lib. It compiles and links properly, But juce Demo crashen in the “MainDemoWindow” constructor.

commandManager->registerAllCommandForTarget(contentComp);

Has any one else noticed this problem?

Regards,
Yogesh

Ok, just had a go of this myself, and was a bit puzzled because although I thought that it used to be compiling the dll correctly, in fact it wasn’t - it was just compiling the static one… and when I fixed this, there were loads of errors that I should have spotted earlier. Sorry about that! I’m going through it now so will have it fixed in the next release. And if I see the same crash you mention, I’ll let you know how to fix it.

Right. This is a really nasty problem.

The crash happens because the dll passes an array to the app, and the app adds items to it. Because arrays are templated, they can’t be exported from a dll, so the app and the dll end up with two separate versions of the array code, which use different allocators. So when one module creates an array, the other module will blow up if it tries to use it.

To be honest, I’ve no idea how you could get around this, except by changing every single interface in the whole library to make sure no templated objects are never passed in or out of a juce class.

Yet another reason why I always use static linking - it’s just so much less hassle!

Instead of embedding the allocator, you should have it as an internal class which is instanced by the object to handle creation/destruction. Boost uses that pattern for everything templated to prevent anything like that.

Yes, I am sorry for talking about boost so much recently, but everything I’ve talked about it is just so appropriate for what is being talked about. >.>