跨dll使用静态类变量/函数

Gas*_*sim 3 c++ dll static shared-libraries

我需要帮助访问跨 DLL/主程序的全局函数。我有一个班级基地

基数

#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; }

};
Run Code Online (Sandbox Code Playgroud)

main.cpp(主应用程序)(此处预定义了 MAIN_DLL)

Filesystem * Base::filesystem = 0;
Logger * Base::logger = 0;
System * Base::system = 0;
Run Code Online (Sandbox Code Playgroud)

当我从 dll访问时:

System * system = Base::sys();
if(system == 0) std::cout << "Error";
Run Code Online (Sandbox Code Playgroud)

谢谢,加西姆

Jam*_*nze 5

这取决于系统,但您必须确保包含成员函数和静态成员数据定义的 DLL 中的符号正确导出符号,并且使用它们的 DLL 正确导入它们。在 Linux 下,这意味着-E在链接可执行文件时使用该选项(如果在可执行文件中定义了符号);在 Windows 下,您通常必须使用条件编译的编译器扩展,请参阅__declspec;Microsoft 编译器不支持标准 C++ 中的 DLL。

编辑:

这是一个适用于我的系统(VC 2010)的示例:

在啊:

#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
Run Code Online (Sandbox Code Playgroud)

在 A.cpp 中:

#include "A.h"

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

void
InA::setDest( std::ostream& dest )
{
    ourDest = &dest;
}
Run Code Online (Sandbox Code Playgroud)

在 main.cpp 中:

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

int
main()
{
    InA::setDest( std::cout );
    std::cout << InA::getStream() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译并链接到:

cl /EHs /LDd /DDLL_A A.cpp
cl /EHs /MDd main.cpp A.lib
Run Code Online (Sandbox Code Playgroud)

据我了解(我更像是一个 Unix 人),所有成为 dll 一部分的 .cpp 都应该在调用编译器的命令行中包含 /DDLL_A;其他人都不应该。在 Visual Studios 中,这通常是通过为每个 dll 和每个可执行文件使用单独的项目来实现的。在项目的属性中,有一个条目 ConfigurationProperties→C/C++→Preprocessor→Preprocessor Definitions;只需在DLL_A那里添加(但仅在生成 的一个项目中A.ddl)。