Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use static class variable/function across dlls

I need help access global functions across DLLs/main program. I have a class Base

Base.h

#ifdef MAIN_DLL
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif


class Base {
private:
    DECLSPEC static Filesystem * filesystem;
    DECLSPEC static Logger * logger;
    DECLSPEC static System * system;

public:

    static void setFilesystem(Filesystem * filesystem_);
    static void setApplication(Application * application_);
    static void setLogger(Logger * logger_);
    static void setSystem(System * system_);

    static Filesystem * fs() { return filesystem; }
    static Logger * log() { return logger; }
    static System * sys() { return system; }

};

main.cpp (main application) (MAIN_DLL is predefined here)

Filesystem * Base::filesystem = 0;
Logger * Base::logger = 0;
System * Base::system = 0;

When I access from the dll:

System * system = Base::sys();
if(system == 0) std::cout << "Error";

Thanks, Gasim

like image 595
Gasim Avatar asked Feb 01 '26 23:02

Gasim


1 Answers

This is system dependent, but you'll have to ensure that the symbols in the DLL containing the definitions of the member functions and static member data correctly exports the symbols, and that the DLL using them correctly imports them. Under Linux, this means using the -E option when linking the executable (if the symbols are defined in the executable); under Windows, you usually have to use conditionally compiled compiler extensions, see __declspec; Microsoft compilers do not support DLL's in standard C++.

EDIT:

Here's an example that works on my system (VC 2010):

In A.h:

#ifndef A_h_20111228AYCcNClDUzvxOX7ua19Fb9y5
#define A_h_20111228AYCcNClDUzvxOX7ua19Fb9y5

#include <ostream>

#ifdef DLL_A
#define A_EXPORT __declspec(dllexport)
#else
#define A_EXPORT __declspec(dllimport)
#endif

class A_EXPORT InA
{
    static std::ostream* ourDest;
public:
    static void setDest( std::ostream& dest );
    static std::ostream* getStream() { return ourDest; }
};
#endif

In A.cpp:

#include "A.h"

std::ostream* InA::ourDest = NULL;

void
InA::setDest( std::ostream& dest )
{
    ourDest = &dest;
}

In main.cpp:

#include <iostream>
#include "A.h"

int
main()
{
    InA::setDest( std::cout );
    std::cout << InA::getStream() << std::endl;
    return 0;
}

Compiled and linked with:

cl /EHs /LDd /DDLL_A A.cpp
cl /EHs /MDd main.cpp A.lib

As I understand it (I'm more a Unix person), all of the .cpp which become part of the dll should have /DDLL_A in the command line which invokes the compiler; none of the others should. In Visual Studios, this is usually achieved by using separate projects for each dll and each executable. In the properties for the project, there's an entry ConfigurationProperties→C/C++→Preprocessor→Preprocessor Definitions; just add DLL_A there (but only in the one project that generates A.ddl).

like image 137
James Kanze Avatar answered Feb 04 '26 11:02

James Kanze



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!