【问题标题】:static variables empty when using dynamic loading of library使用动态加载库时静态变量为空
【发布时间】:2017-07-10 16:39:18
【问题描述】:

我有这个设置:

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() - 我无法发布实际名称。

我在这里误会了什么?

【问题讨论】:

  • 你能贴出不起作用的代码,而不是一个,那行吗?
  • @RadosławCybulski 更新了问题。
  • 好奇extern void addToStrings(std::string s);应该是 extern "C" void addToStrings(std::string s); 可能是 cpp 破坏了这个名字?
  • @atomSmasher 里面其实是extern "C"我更新了代码。
  • std::vector<:string> & v = ClassA::getStrings();这是如何编译的? ClassA::getStrings() 不返回引用。

标签: c++ dynamic-loading


【解决方案1】:

我找到了答案。

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

我认为它可能对可能有问题的人有用,尽管我认为可能性不大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    相关资源
    最近更新 更多