使用跨dll的静态类变量/函数 [英] use static class variable/function across dlls

查看:274
本文介绍了使用跨dll的静态类变量/函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助访问跨DLL /主程序的全局函数。我有一个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_DLL在此预定义)

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

当我从dll 访问时:

  System * system = Base :: sys(); 
if(system == 0)std :: cout<< 错误;

感谢,
Gasim

解决方案

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



编辑:



这是一个在我的系统上工作的示例(VC 2010):



在Ah:

  #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

在A.cpp中:

  #includeAh

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

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

在main.cpp中:

  #include< iostream> 
#includeA.h

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

编译并链接到:


$ b b

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

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

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

解决方案

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).

这篇关于使用跨dll的静态类变量/函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆