动态库的链接问题

发布于 2024-11-04 19:12:24 字数 2369 浏览 1 评论 0原文

我正在尝试动态加载实现在另一个库中定义的基类的库。我已按照此处描述的说明进行操作:

http://www.linuxjournal.com/article /3687?page=0,1

我创建了一个形状类并将其放入一个单独的库中(不是真正的库,因为它只是一个头文件,但这样说),我还创建了两个动态库,圆形和方形,继承自形状和实现draw方法并在工厂映射中注册它们的maker函数。让我向您展示代码:

shape.h:

#ifndef __SHAPE_H
#define __SHAPE_H
#include <map>
#include <string>

// base class for all shapes
class shape{
public:
// our global factory
virtual void draw()=0;
};

// typedef to make it easier to set up our factory
typedef shape *maker_t();
extern std::map<std::string, maker_t *, std::less<std::string> > factory;


#endif // __SHAPE_H

circle.hcircle.cpp

#ifndef __CIRCLE_H
#define __CIRCLE_H

#include "shape.h"

class circle : public shape
{
public:
   void draw();
};
#endif // __CIRCLE_H

:

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

void circle::draw()
{
    // simple ascii square
std::cout << "\n";
std::cout << "      ****\n";
std::cout << "    *      *\n";
std::cout << "   *        *\n";
std::cout << "   *        *\n";
std::cout << "   *        *\n";
std::cout << "    *      *\n";
std::cout << "      ****\n";
std::cout << "\n";
}

extern "C"
{
shape *maker()
{
    return new circle;
}
class proxy
{
    public:
        proxy()
        {
            // register the maker with the factory
            factory["circle"] = maker;
        }
};
// our one instance of the proxy
proxy circle_p;
}

我不会进入正方形,因为它几乎与圆相同,也不是动态加载库的实际“客户端”,因为它实际上可以工作。

现在我的问题是,如果你在circle.so中有其他类和功能(这是我的情况),并且在某些情况下你需要在编译时链接(-l选项),我会遇到问题。我创建了一个测试客户端库,它不是动态加载循环,而是在编译时执行此操作。链接器失败并显示以下输出:

Invoking: GCC C++ Linker
g++ -rdynamic -L/home/lizardking/workspace/dynclientest/Debug/libs -o "test2"  ./src/test2.o   -ldynlib_circle
/home/lizardking/workspace/dynclientest/Debug/libs/libdynlib_circle.so: undefined reference to `factory'
collect2: ld returned 1 exit status

此测试应用程序中的 main.cpp 只是一个 hello world!:

#include <iostream>
using namespace std;

int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}

我真的不知道为什么链接器一直抱怨地图......有什么想法吗???

谢谢!

I'm trying to dynamically load libraries that implement a base class, defined in another library. I've followed instructions depicted here:

http://www.linuxjournal.com/article/3687?page=0,1

I created a shape class and put it in a separated library (not a real library since its just a header file, but put it that way), also I created two dynamic libraries, circle and square, that inherit from shape and implement the draw method and register their maker function in the factory map. Let me show you the code:

shape.h:

#ifndef __SHAPE_H
#define __SHAPE_H
#include <map>
#include <string>

// base class for all shapes
class shape{
public:
// our global factory
virtual void draw()=0;
};

// typedef to make it easier to set up our factory
typedef shape *maker_t();
extern std::map<std::string, maker_t *, std::less<std::string> > factory;


#endif // __SHAPE_H

circle.h

#ifndef __CIRCLE_H
#define __CIRCLE_H

#include "shape.h"

class circle : public shape
{
public:
   void draw();
};
#endif // __CIRCLE_H

circle.cpp:

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

void circle::draw()
{
    // simple ascii square
std::cout << "\n";
std::cout << "      ****\n";
std::cout << "    *      *\n";
std::cout << "   *        *\n";
std::cout << "   *        *\n";
std::cout << "   *        *\n";
std::cout << "    *      *\n";
std::cout << "      ****\n";
std::cout << "\n";
}

extern "C"
{
shape *maker()
{
    return new circle;
}
class proxy
{
    public:
        proxy()
        {
            // register the maker with the factory
            factory["circle"] = maker;
        }
};
// our one instance of the proxy
proxy circle_p;
}

I won't go into the square, since it's almost identical to the circle neither the actual "client" that dynamically loads the libraries, since it actually works.

Now my question is, in case you have other classes and functionality in the circle.so (this is my case), and in some cases you need link at compile time (-l option), I run into problems. I created a test client library that instead of dynamically loading circle, it does it at compile time. Linker fails with the following output:

Invoking: GCC C++ Linker
g++ -rdynamic -L/home/lizardking/workspace/dynclientest/Debug/libs -o "test2"  ./src/test2.o   -ldynlib_circle
/home/lizardking/workspace/dynclientest/Debug/libs/libdynlib_circle.so: undefined reference to `factory'
collect2: ld returned 1 exit status

The main.cpp from this test app is just a hello world!:

#include <iostream>
using namespace std;

int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}

I really dunno why the linker is complaining all the time about the map....any ideas???

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南风起 2024-11-11 19:12:24

您仅在 shape.h 中将 factory 声明为 extern。

您应该将类​​似以下内容放入

std::map<std::string, maker_t *, std::less<std::string> > factory;

shape.cpp 中,以在 shape.o 中保留空间(即创建定义的符号)。

You have only declared factory as extern in shape.h.

You should put something like:

std::map<std::string, maker_t *, std::less<std::string> > factory;

into shape.cpp to reserve space (i.e. create a defined symbol) in shape.o.

笑饮青盏花 2024-11-11 19:12:24

如果您仔细阅读该错误,您就会明白其原因。

/home/lizardking/workspace/dynclientest/Debug/libs/libdynlib_circle.so: undefined reference tofactory`

它告诉您它找不到对名为 factory 的对象的引用,它还会告诉您访问该对象的位置 libdynlib_circle.so

检查您的 libdynlib_circle.so factory 对象在 shape.h 中声明extern。当您在变量或对象上使用 extern 关键字时,它会告诉编译器将定义特定变量或对象(创建 )在其他一些源文件中,并且声明 extern(shape.so) 的位置仅引用相同的变量。在您的情况下,此 factory 对象未在任何中定义或创建源文件,因此出现 undefined reference to 的错误factory 因为 source.so 找不到创建的 factory obj。

因此,为了避免错误,您需要在源文件之一中定义 factory 对象。

std::map<std::string, maker_t *, std::less<std::string> > factory;

If you read the error carefully, You will understand the reason for it.

/home/lizardking/workspace/dynclientest/Debug/libs/libdynlib_circle.so: undefined reference tofactory`

It tells you that it cannot find reference to a object named factory, and it also tells you the location from where this object is getting accessed libdynlib_circle.so

Checking in your libdynlib_circle.so the factory object is declared as extern in shape.h. When you use the extern keyword on a variable or object it tells the compiler that the particular variable or object will be defined(created) in some other source file and the location where it is declared extern(shape.so) just references the same variable.In your case this factory object is not defined or created in any of the source files and hence the error that undefined reference to factory because source.so cannot find a created factory obj.

Hence, to avoid the error you need to define the factory object in one of the source files.

std::map<std::string, maker_t *, std::less<std::string> > factory;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文