C++ 从c+中的动态库访问静态类成员+;

C++ 从c+中的动态库访问静态类成员+;,c++,static,shared-libraries,dlopen,dynamic-library,C++,Static,Shared Libraries,Dlopen,Dynamic Library,首先,这是我的第一个问题,我通常是在寻找答案,所以如果我犯了一些错误,很抱歉 我试图从动态库访问静态类的成员。问题是,我不知道为什么,这个静态类成员的内存不一样,这取决于我如何访问它 我有一个主程序执行多项任务并调用多个动态库(使用dlopen/dlsym)。这些动态库应该访问属于主程序的一些变量。如果这些变量不是静态的,我可以共享一个指针,这样我就不会遇到这些问题。但是,当这些变量是静态的时,我发现了一些问题 我在linux下运行这个程序,使用g++7.5.0和Glibc2.27 这是一个小示

首先,这是我的第一个问题,我通常是在寻找答案,所以如果我犯了一些错误,很抱歉

我试图从动态库访问静态类的成员。问题是,我不知道为什么,这个静态类成员的内存不一样,这取决于我如何访问它

我有一个主程序执行多项任务并调用多个动态库(使用dlopen/dlsym)。这些动态库应该访问属于主程序的一些变量。如果这些变量不是静态的,我可以共享一个指针,这样我就不会遇到这些问题。但是,当这些变量是静态的时,我发现了一些问题

我在linux下运行这个程序,使用g++7.5.0和Glibc2.27

这是一个小示例,显示了我的问题: 主程序
main.cpp
修改静态变量
value
并调用动态库
libShare.so
来创建
sharedived
对象。此对象访问静态变量
以打印它

/*** Main.cpp ***/
#include <dlfcn.h>
#include "ShareBase.hpp"

int StaticClass::value = 1;

int main() {
    StaticClass::value = 3;
    void* hdl = dlopen("./lib/libShare.so", RTLD_LAZY | RTLD_GLOBAL);
    ShareBase*(*obj)() = (ShareBase*(*)())dlsym(hdl,"createObject");
    obj()->BaseValue();
    obj()->DerivedValue();
    delete (obj());
    dlclose(hdl);
    return 0;
}

/*** ShareBase.hpp ***/
#pragma once

class StaticClass {
    public:
    StaticClass() = delete;
    ~StaticClass() = delete;
    static int value;
};
class ShareBase {
    public:
    ShareBase();
    virtual ~ShareBase();
    void BaseValue();
    virtual void DerivedValue() = 0;
};

/*** ShareBase.cpp ***/
#include "ShareBase.hpp"
#include <stdio.h>

ShareBase::ShareBase() {}
ShareBase::~ShareBase() {}
void ShareBase::BaseValue() {
    printf("Base: %d --> %p\n", StaticClass::value, (void*)&StaticClass::value);
}

/*** ShareDerived.hpp ***/
#pragma once
#include "ShareBase.hpp"

class ShareDerived:public ShareBase {
    public:
    ShareDerived();
    virtual ~ShareDerived();
    void DerivedValue();
};

extern "C" {
    ShareBase* createObject() {
        auto *m = new ShareDerived();
        return (ShareBase*)m;
    }
}

/*** ShareDerived.cpp ***/
#include "ShareDerived.hpp"
#include <stdio.h>

ShareDerived::ShareDerived() {}
ShareDerived::~ShareDerived() {}
void ShareDerived::DerivedValue() {
    printf("Derived: %d --> %p\n", StaticClass::value, (void*)&StaticClass::value);
    printf("Derived: ");
    BaseValue();
}
/***Main.cpp***/
#包括
#包括“ShareBase.hpp”
int StaticClass::value=1;
int main(){
StaticClass::value=3;
void*hdl=dlopen(“./lib/libShare.so”,RTLD_LAZY | RTLD_GLOBAL);
ShareBase*(*obj)(=(ShareBase*(*)())dlsym(hdl,“createObject”);
obj()->BaseValue();
obj()->DerivedValue();
删除(obj());
dlclose(hdl);
返回0;
}
/***ShareBase.hpp***/
#布拉格语一次
类静态类{
公众:
StaticClass()=删除;
~StaticClass()=删除;
静态int值;
};
类共享库{
公众:
ShareBase();
虚拟~ShareBase();
void BaseValue();
虚空DerivedValue()=0;
};
/***ShareBase.cpp***/
#包括“ShareBase.hpp”
#包括
ShareBase::ShareBase(){}
ShareBase::~ShareBase(){}
void ShareBase::BaseValue(){
printf(“基:%d-->%p\n”,StaticClass::value,(void*)和StaticClass::value);
}
/***shared.hpp***/
#布拉格语一次
#包括“ShareBase.hpp”
类Share派生:公共ShareBase{
公众:
sharedired();
虚拟~sharedived();
void DerivedValue();
};
外部“C”{
ShareBase*createObject(){
auto*m=新的sharedived();
返回(ShareBase*)m;
}
}
/***shared.cpp***/
#包括“sharedived.hpp”
#包括
ShareDerived::ShareDerived(){}
ShareDerived::~ShareDerived(){}
void ShareDerived::DerivedValue(){
printf(“派生的:%d-->%p\n”、StaticClass::value、(void*)和StaticClass::value);
printf(“派生:”);
BaseValue();
}
这是我用来编译此示例的makefile:

CXX:=g++
CXX_标志:=-Wall-Wextra-std=c++17-ggdb
BIN:=BIN
SRC:=SRC
INC:=包括
LIB:=LIB
EXE:=测试
全部:主库
main:$(BIN)/$(EXE)
ar rcs$(LIB)/libMain.a$(BIN)/Main.o$(BIN)/ShareBase.o
lib:$(lib)/libShare.so
$(BIN)/$(EXE):$(BIN)/Main.o$(BIN)/ShareBase.o
$(CXX)$(CXX_标志)-I$(INC)-L$(LIB)$^-o$@-ldl
$(LIB)/libShare.so:$(BIN)/ShareDerived.o
$(CXX)$(CXX_标志)-I$(INC)-L$(LIB)-shared$^-o$@-lMain
$(BIN)/%.o:$(SRC)/%.cpp
$(CXX)$(CXX_标志)-I$(INC)-L$(LIB)-fPIC-c-o$@$<
清洁:
-rm$(BIN)/*$(LIB)/*
这是我得到的输出:

Base:3-->0x55e8df87f010 0x7f40b5918090 0x7f40b5918090
您正在将
Main.cpp
直接链接到共享库中

您正在运行
Main.cpp
,作为可执行文件的一部分

因此,存在静态类成员的重复实例。这违反了一个定义规则,并导致未定义的行为。这就是你观察到的行为的解释


您这样做很可能是因为未链接
-lMain
显示的程序出现故障。发生这种情况的原因完全无关——内联C-linkage函数从未在共享库中实例化,因为编译器在编译共享库时没有理由实例化它。您可能无法找出原因,但发现链接
Main
解决了segfault,但导致了这种行为。这是一个经典的XY问题。最初,你的问题应该是为什么会出现SEGFULT。

你读过了吗?您是否同时使用和来理解程序的行为?好的。我明白问题所在。我正试图更改我的makefile以避免重复的实例,但是,到目前为止,我还不能。如果你能帮助我,我将不胜感激。我将共享库与
-lMain
链接,因为它使用的是主程序成员和函数(在本例中为
ShareBase.cpp
),所以共享库需要它。确切地说,如果我删除它,就会出现分割错误,但从我的角度来看,这是正常的,我做到了。我将用新的Makefile更新我的问题。谢谢你@sam!
$(CXX) $(CXX_FLAGS) -I$(INC) -L$(LIB) -shared $^ -o $@ -lMain