静态对象未在 VC 2010 的静态库中链接。如何强制链接?

发布于 2024-10-23 21:11:44 字数 682 浏览 1 评论 0原文

我有一个静态工厂,它依赖自身的静态成员将类注册到工厂系统中。

class Foo_A_Maker : public FooFactory<Foo, const std::string &>
{
private:
    // Register this as a type using a static instance of itself.
    // This is really the only time it is created. That's why the
    // constructor is private.
    Foo_A_Maker() : FooFactory("Foo_A") {}
    static const Foo_A_Maker registerThis;

public:
    virtual std::shared_ptr<Foo> MakeProduct(const std::string& params) const;
};

这在我的所有项目中已经有效多年,但现在我已将其添加到静态库中。在静态库中,构造函数永远不会被调用,对象也永远不会注册。如果我将此代码放入 exe 项目中,它会再次工作。我已确定这不是通过引入链接时间错误进行链接。

我错过了什么吗?我可以强制链接吗?如果我跨编译边界使用它,EXE 项目可以添加自己的工厂吗?

谢谢大家。

I have a static factory that relies on a static member of itself to register the class into the factory system.

class Foo_A_Maker : public FooFactory<Foo, const std::string &>
{
private:
    // Register this as a type using a static instance of itself.
    // This is really the only time it is created. That's why the
    // constructor is private.
    Foo_A_Maker() : FooFactory("Foo_A") {}
    static const Foo_A_Maker registerThis;

public:
    virtual std::shared_ptr<Foo> MakeProduct(const std::string& params) const;
};

This has worked for years in all my projects, but now I have added it to a static library. In the static library, the ctor is never called and the object never registers. If I put this code in the exe project it works again. I have determined that this is not linking by introducing a link time error.

Am I missing something? Can I force a link? And if I use this across compilation boundaries can the EXE project add its own factories?

Thanks all.

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

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

发布评论

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

评论(2

青瓷清茶倾城歌 2024-10-30 21:11:44

这就是库应该如何工作 - 链接器只获取它需要的符号(从外部引用)。解决这个问题的正确方法是提供一个 init 函数。

对于 Visual Studio,您可以找到所需的确切符号名称,并将 /INCLUDE 作为命令行选项传递给链接器。您可以尝试使用/OPT:NOREF - 听起来它可以工作,但还没有测试过。

This is how libs are supposed to work - the linker only takes the symbols it needs (referenced from the outside). The correct way of solving this is to provide an init function.

For Visual Studio you can find the exact symbol name that you need, and pass /INCLUDE as a command-line option to the linker. You can try with /OPT:NOREF - it sounds like it could work, but haven't tested it.

私藏温柔 2024-10-30 21:11:44

类定义中的静态成员变量需要与该类外部的相同变量匹配(我不清楚每个部分的确切术语)。这意味着在类之外的某个 CPP 文件中,您需要这样写:

Foo_A_Maker Foo_A_Maker::registerThis;

这是创建对象的点(如果没有它,它可以在任何程序中工作,这有点奇怪)。将其放入其中一个 CPP 文件中就可以了。

您还应该能够将其放入 CPP 文件中,而无需将其声明为类中的静态成员。这将是更容易的路线。也就是说,删除静态并将其放入 CPP 文件中:

Foo_A_Make registerThis;

A static member variable in the class definition needs to be matched with the same variable outside of that class (I'm not clear on the exact terms for each part of this). That means in some CPP file, outside of the class, you need to write this:

Foo_A_Maker Foo_A_Maker::registerThis;

This is the point at which the object is created (that it works in any program without this is a bit strange). Place this inside one of the CPP files and you should be alright.

You should also just be able to put this inside a CPP file without declaring it as a static member in the class. This would be the easier route. That is, remove the static and just put this in a CPP file:

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