相关疑难解决方法(0)

如何在链接到可执行文件时强制将对象文件包含在静态库中?

我有一个C++项目,由于其目录结构被设置为静态库A,它链接到共享库B,它链接到可执行文件C.(这是使用CMake的一个跨平台的项目,所以在Windows上我们得到的A.lib,B.dllC.exe,和在Linux上我们得到的libA.a,libB.soC).图书馆A有一个初始化函数(A_init在定义A/initA.cpp),即从库调用B的初始化函数(B_init,定义于B/initB.cpp),从C主要调用.因此,当链接时B,A_init(和所有符号中定义的initA.cpp)被链接到B(这是我们期望的行为).

问题在于,A库还定义了一个动态加载的函数(Af,在A/Afort.f其中定义)(即LoadLibrary/ GetProcAddress在Windows上和dlopen/ dlsym在Linux上).由于没有Af来自库的引用B,A/Afort.o因此不包括符号B.在Windows上,我们可以通过使用pragma人工创建引用:

#pragma comment (linker, "/export:_Af")
Run Code Online (Sandbox Code Playgroud)

由于这是一个pragma,它只适用于Windows(使用Visual Studio 2008).为了让它在Linux上运行,我们尝试将以下内容添加到A/initA.cpp:

extern void Af(void);
static void (*Af_fp)(void) = …
Run Code Online (Sandbox Code Playgroud)

c++ linux linker static-libraries

22
推荐指数
3
解决办法
1万
查看次数

Boost.Test测试静态库

我正在使用Boost.Test进行单元测试.

由于几个原因,我想在不同的静态库上编写单元测试用例.

问题是,当我这样做时,自动注册器不起作用.

例如,如果我有类似的东西:

// foo_tests.cpp
#define BOOST_TEST_MODULE "Foo"
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE( Bar )
{
    BOOST_CHECK( false );
}
// used to generate libFooTests.a

// main.cpp
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
// used to generate main.o
Run Code Online (Sandbox Code Playgroud)

然后,如果我将main.o与libFooTests.a链接并执行最终的二进制文件,它会说:

Test setup error: test tree is empty

如果我直接从源代码创建二进制文件,一切正常,但我不能使用自动注册在静态库中编写单元测试.

我能做到吗?

我需要定义一些宏吗?我需要从libFooTests.a导出一些符号?

谢谢!

c++ unit-testing static-libraries boost-test

11
推荐指数
1
解决办法
1956
查看次数

C++类型在列表中自行注册的最佳方法是什么?

假设我有一些每类数据:(AandB.h)

class A
{
public:
   static Persister* getPersister();
}

class B
{
public:
   static Persister* getPersister();
}
Run Code Online (Sandbox Code Playgroud)

......还有很多课程.我想做的事情如下:

persistenceSystem::registerPersistableType( A::getPersister() );
persistenceSystem::registerPersistableType( B::getPersister() );
...
persistenceSystem::registerPersistableType( Z::getPersister() );
Run Code Online (Sandbox Code Playgroud)

......为每个班级.

我的问题是:有没有办法自动构建每类数据列表,这样我就不必枚举大块中的每个类型(如上例所示)?

例如,您可以这样做的一种方法是:(AutoRegister.h)

struct AutoRegisterBase
{
   virtual ~AutoRegisterBase() {}
   virtual void registerPersist() = 0;
   static AutoRegisterBase*& getHead()
   {
      static AutoRegisterBase* head= NULL;
      return head;
   }

   AutoRegisterBase* next;
};

template <typename T>
struct AutoRegister : public AutoRegisterBase
{
   AutoRegister() { next = getHead(); getHead() = this; }

   virtual void registerPersist()
   {
       persistenceSystem::registerPersistableType( T::getPersister() …
Run Code Online (Sandbox Code Playgroud)

c++

10
推荐指数
1
解决办法
2815
查看次数

编译时的C++类型注册技巧

我有以下情况:假设我有一堆类型(仿函数),我想在编译期间注册/编译,最好是像boost :: mpl :: vector.你知道这么做的诀窍吗?

我的愿望是拥有实现仿函数类型和注册文件的hpp文件,其中宏将类型引入编译.

例如

// registered.hpp
REGISTER("functor1.hpp") // implementation
REGISTER("functor2.hpp")
...
boost::mpl::vector<...> types; // full registration vector
Run Code Online (Sandbox Code Playgroud)

希望这是有道理的.谢谢

c++ macros templates

10
推荐指数
1
解决办法
3434
查看次数

使用MSVC强制符号导出

我有一个应用程序和DLL文件中的几个插件.插件通过导出库使用应用程序中的符号.应用程序链接在几个静态库中,这是大多数符号的来源.只要应用程序使用符号,这就可以正常工作.如果那里没有使用符号,我在编译DLL时会遇到链接器错误.

如何强制导出仅在插件中使用的符号?

为了触发导出,我尝试过这样的事情:

    class MyClassExporter
    {
        MyClass mInstance;
    public:
        MyClassExporter() {}
    };
    static MyClassExporter TheMyClassExporter;
Run Code Online (Sandbox Code Playgroud)

在其中一个静态库中,应用程序由强制导出组成,这不起作用.

回应Greg(感谢答案)并澄清:我要强制导出的类是MyClass(已定义__declspec(...),具体取决于我想要导出或导入).MyClassExport是我试图强制将未使用的(就应用程序而言)符号包含在应用程序中.我想"触摸"符号,以便链接器将它们识别为已使用并将它们包含在应用程序中,以便它可以将这些符号导出到我的插件中.将静态库链接到插件不是一种选择,因为它们包含可复制的单例(app和DLL各自都有自己的静态变量副本).

c++ dll plugins visual-c++

7
推荐指数
1
解决办法
1万
查看次数

C++静态类成员未在*静态库中初始化*

我目前正面临着一个令人讨厌的C++问题.

实际上,我甚至不明白为什么在过去的20年里我没有面对它:(

在我目前的上下文中,我们大量使用与我们专有的静态库静态链接的c ++可执行文件(主要是在Linux嵌入式系统中).出于技术和优化原因,我们确实使用静态库.

事实上,在过去的几年里,我曾经创建了共享库...

所以我开始用静态类成员编写一些类.如下:

class Inner
{
public:
   Inner()
   {
     std::cout << "CTOR Inner" << std::endl;
   }
};

class A
{
static Inner _inner;

...
};

// in the .cpp

Inner A::_inner;

///////////////////////
Run Code Online (Sandbox Code Playgroud)

非常基本的用例,不是吗?

但在我的单元测试中,与lib链接,我无法std::cout在控制台中看到该语句.然而,如果我将我的类Inner和A移动到可执行源代码中......它可以正常工作.

我确信这是一个非常基本的问题,我意识到过去几年我从未面对过这个问题.这是与编译器有关的问题吗?请注意,我在Windows和Linux上测试了这两种情况(Debian,Gcc 4.9).

欢迎任何想法.

Z.

c++ static static-libraries

4
推荐指数
1
解决办法
686
查看次数

使用静态初始化的副作用进行一次性初始化

我想在共享库中初始化一些查找表,我想看看这是否是一种有效的方式,如果它继续在更多的库中使用它我将要编写.

typedef std::map<std::string, int> NAME_LUT;
NAME_LUT g_mLUT;
namespace
{
    bool OneTimeInit() 
    {
        ::g_mLUT.insert(NAME_LUT::value_type("open",          1));
        ::g_mLUT.insert(NAME_LUT::value_type("close",         2));
        return true;
    }
    bool bInit = OneTimeInit(); // Just to make initialization happen
}
Run Code Online (Sandbox Code Playgroud)

它似乎在Visual Studio和gcc(Linux)上都能正常工作.只有gcc抱怨bInit没有在任何地方使用.

  1. 是否可能优化初始化(bInit未使用),或语言不允许(由于副作用).
  2. 它确实看起来像处理一次性初始化的良好的跨平台方式,但我不确定这是否是最好的方法.
  3. OneTimeInit声明静态是否有意义?(即使用static bool OneTimeInit() {...}),或单独使用命名空间是使其成为此编译单元唯一的更好方法

c++ namespaces initialization shared-libraries

0
推荐指数
1
解决办法
1521
查看次数

用于在任意翻译单元中的 main 之前执行任意代码的 C++ 成语

我有一个带有我的main()函数的翻译单元和另一个没有 main 的翻译单元。假设即使我只控制第二个而无法触摸第一个。

现在,由于我不会讨论的原因,我希望能够在运行之前运行一些代码main()。我知道这可以通过使用函数调用初始化全局变量来完成,但我想隐藏这一点 - 尽可能少地使用宏(我敢说不使用宏吗?可能不可能,C++ 中没有适当的静态块)

什么是优雅的,或者我们可以说,不是很丑的做这件事的方式?更清楚地说,我正在寻找可以多次使用此功能的东西,而不仅仅是让它工作一次的东西。我希望它尽可能接近:

// ... at global scope ...
static {
    // my code here
}
Run Code Online (Sandbox Code Playgroud)

PS:这个问题与这个关于初始化静态类成员的问题有关,但不一样。它还希望清楚地反驳这个声明,它不能在 C++ 中完成

注意:是的,我知道静态初始化顺序失败,不需要提醒我……而且我不是要求绕过它的东西。显然,静态运行代码需要一些谨慎。

c++ idioms static-block

0
推荐指数
1
解决办法
620
查看次数

有什么需要,本地静态变量在编译期间分配内存?

我正在学习staticC中的变量,并且知道static变量的内存是在编译时分配的(在编译期间需要分配多少内存并且在编译时计算其虚拟地址,在程序加载时分配实际内存)在任一数据中segment/.bss取决于是否已初始化

我在一些网站帖子中看到,由于对象/变量将采用的大小是基于变量类型预定义的,因此内存在编译时分配.但是,如果局部static变量在函数中定义且其范围仅在函数内,我不理解这种情况的必要性.

请考虑以下代码段:

void func()
{
    static int i;
    /*some logic*/
} 

void func1()
{
    static int data[10] = {1,2,3,4,5,6,7,8,9,10};
    /*some logic*/
}

int main()
{
    /*logic not involving func() and func1()*/
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,函数funcfunc1没有在程序中调用,但是static一旦程序加载(从我学到的)实际上没有使用,就会分配这些函数中的变量的内存.因此,有了这个缺点,为局部static变量分配内存的用途是什么.为什么编译器在通过函数时不能在数据段中为它们分配内存.

我已经经历了关于此的堆栈溢出问题,无法得到确切的答案 请帮助!

c c++

0
推荐指数
1
解决办法
180
查看次数