dynamic #include?! Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

dynamic #include?!

Post by mael15 »

hi,
my program uses some national instruments drivers that have 1.3gb installer. since i do not always need these drivers, i would like to only load them in my program if they are installed. i already figured out that i can check for their installation by using

Code: Select all

if(wxRegKey(wxRegKey::HKLM, "SOFTWARE\\National Instruments\\NI-DAQmx\\CurrentVersion").Exists()){ ... }
but how can i have the #include statements only if these drivers are installed? maybe using wxDynamicLibrary?
i am missing some basic understanding here, maybe someone can point me to a tutorial? i do not know what keywords to search for.
thank you!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: dynamic #include?!

Post by ONEEYEMAN »

Hi,
C++ does not support conditional inclusion f the headers.

In other words you either include or not include.

Why you don't want to include those files? It does not cost anything. And you can probably do dynamic load of those libraries and call the function inside them, but then you code will not depend on them at all.

Thank you.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: dynamic #include?!

Post by PB »

Adding to what ONEEYEMAN wrote:

If you want to call functions from a DLL that may not be available when your program starts, you need to use run-time dynamic linking. If you would link such functions "normally" (load-time dynamic linking using an imported library) and the DLL could not be found, your program will not start.

You would use run-time linking not because a programmer did not want to install an SDK, you do that when the DLL (or a function in DLL may be available only since a certain version of the DLL) may not be present at the user computer and you still want the application to start - run-time linking is more work than the usual load-time linking, header files are not used as the functions cannot be just simply called and are useful only for obtaining the information about function properties.

The following example demonstrates how to call a function from DLL loaded at run-time, As you can see, it's quite a hassle even with a single simple function.

Code: Select all

#include <wx/wx.h>
#include <wx/dynlib.h>

class MyApp : public wxApp 
{
public: 
    bool OnInit() 
    { 
        // The function we want to call is declared as
        // int ShellAbout(_In_opt_ HWND hWnd, _In_  LPCTSTR szApp, _In_opt_ LPCTSTR szOtherStuff, _In_opt_ HICON hIcon);

        // first create the function typedef
        // The function actually exists in ANSI (ending with A) and Unicode versions (ending with W)
        // we want the Unicode version
        typedef int (WINAPI *ShellAboutW_t) (HWND, LPCTSTR, LPCTSTR, HICON);
                      
        // declare the function variable
        ShellAboutW_t pfnShellAboutW = NULL;                
        wxDynamicLibrary dllShell32; // ShellAbout is in shell32.dll
        
        if ( !dllShell32.Load(wxS("shell32.dll"), wxDL_VERBATIM | wxDL_QUIET) )
        {
            wxMessageBox("Could not load shell32.dll.");
            return false;            
        }
        
        wxDL_INIT_FUNC(pfn, ShellAboutW, dllShell32);
        if ( !pfnShellAboutW )
        {
            wxMessageBox("Could not load ShellAboutW().");
            return false;
        }
        
        wxString title("wxWidgets application");
        wxString hello("Hello from wxWidgets!");
        
        int result = pfnShellAboutW(NULL, title.wc_str(), hello.wc_str(), NULL);                                              
        
        return false;
    }
}; 
wxIMPLEMENT_APP(MyApp);
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: dynamic #include?!

Post by mael15 »

thank you for your explanations!
so, do I understand it correctly: he only way to use my program when these dlls are not installed is to use dynamic linking, which is a hassle? or maybe just copying the dlls shown in Dependency Walker manually into the program directory?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: dynamic #include?!

Post by ONEEYEMAN »

Hi,
It is not a hassle, it just a little more code. ;-)
Of course if you want - you can supply those dlls along with you program - pack it up with the installer. Or let the installer download and install the software you depend on.

Thank you.
User avatar
shawnhcorey
Knows some wx things
Knows some wx things
Posts: 41
Joined: Mon Nov 19, 2012 3:29 pm
Location: The Great White North

Re: dynamic #include?!

Post by shawnhcorey »

ONEEYEMAN wrote:C++ does not support conditional inclusion f the headers.
No but it has conditional compiling which works with `#includes. See https://gcc.gnu.org/onlinedocs/cpp/Ifdef.html
WARNING: Highly caffeinated ☕. Approach with caution 🚧.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: dynamic #include?!

Post by PB »

The op meant "dynamic" conditional including, something e.g. scripted languages have where the file may be included on a condition set during the application run.

I doubt one could even build a C++ program without knowing about conditional including, i.e., without include guards
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: dynamic #include?!

Post by ONEEYEMAN »

Well, C++ is not a scripting language - it does not have a translator. ;-)
Post Reply