使用动态加载库时静态变量为空

时间:2017-07-10 16:39:19

标签: c++ dynamic-loading

我有这个设置:

ClassA.h - 属于libA.dll

class ClassA
{
public:
    static std::vector<std::string> getStrings();
    ~ClassA();
    static void addToVector(std::string s);
    static void setAddAllowed(bool addAllowed);
private:
    ClassA();
};

extern "C"
{
  extern void addToStrings(std::string s);
}

ClassA.cpp

#include<ClassA.h>
#include<vector>
static std::vector<std::string> strings;
static bool addAllowed = false;

std::vector<std::string> ClassA::getStrings()
{
    return strings;
}

void ClassA::addToVector(std::string s)
{
    if (addAllowed)
    {
        strings.push_back(s);
    }

}

void ClassA::setAddAllowed(bool add)
{
    addAllowed = add;

}

extern void addToStrings(std::string s)
{
    ClassA::addToVector(s);
}

ClassB.h - 属于libB.dll

class ClassB
{
public:
    static void addString(std::string s);
};

ClassB.cpp

#include<ClassB.h>
#include<ClassA.h> //not present if libA is dynamically loaded.
void ClassB::addString(std::string s)
{
    addToStrings( s ); // problem if addToStrings is called with a function pointer obtained from dynamic loading of libA.dll - libB doesn't depend on libA actually.
}

ClassC.h

class ClassC
{
public:
    static void setAddAllowed(bool add);
};

ClassC.cpp

#include<ClassA.h>
#include<ClassC.h>
void ClassC::setAddAllowed(bool addAllowed)
{
    ClassA::setAddAllowed(addAllowed);
}

Main.cpp的

int main()
{
    ClassB::addString("example1");
    ClassC::setAddAllowed( true );
    ClassB::addString("example2");
    ClassB::addString("example3");

    std::vector<std::string> v = ClassA::getStrings();
}

使用此设置,每件事情都可以正常工作,我可以在ClassA::getStrings()中获取字符串。但问题出现了 - 如果我使用从动态加载的libA的dll获得的函数指针在ClassB中添加字符串,则向量为空。我得到extern function addToStrings的符号作为函数指针并进行调用。在这种情况下,向量v为空。

加载libA并调用函数的示例代码:

typedef void (*addToStringsFP) (std::string s);
addToStringsFP fp = NULL;
Handle libHandle = NULL;
libHandle = LoadImage("libA",0);
fp = (addToStringsFP)FindSymbol(libHandle,"addToStrings");

这只是为了演示我如何加载libA并调用函数指针。 LoadImage,FindSymbol类似于dlopen(), dlsym() - 我无法发布实际名称。

我在这里误解了什么?

1 个答案:

答案 0 :(得分:0)

我找到了答案。

我正在使用的LoadImage函数正在将新图像加载到进程中,而不是首先查看已加载的dll然后加载。 我不得不使用LoadImage的不同版本来加载当前正在处理的图像 - 基本上是共享图像。这解决了这个问题。

我认为对于可能有一些问题的人可能会有所帮助,尽管我认为不太可能。