C ++静态库和平台工具集兼容性

时间:2014-10-03 10:48:22

标签: c++ visual-studio-2008

我最近在Visual Studio 2008中创建了一个静态C ++库。 在这个项目中,我使用了std::string类的一些方法。 现在我想在Visual Studio 2013项目中使用此库。

问题是:
两个Visual Studio版本都使用不同的平台工具集,并且由于链接器错误,项目将无法编译,如:

  

错误4错误LNK2001:未解析的外部符号   " __ declspec(dllimport)public:__ thishisall   的std :: basic_string的,类   std :: allocator> :: basic_string,class std :: allocator>(void)"   (__imp _ρ0 $ @的basic_string DU?$ char_traits @ d @ @@ STD V'$分配器@ d @ @@ 2 STD @@ @ QAE XZ)

有没有办法让库与所有平台工具集兼容并使用一些标准类,如std::string

仅供参考:VS2008使用v90平台工具集,VS2013使用v120平台工具集。

由于点。

修改

如果我在库std::vector中使用一些标准方法,我就不能再实现库了。

这有效:

unsigned int TestClass::TestMethod()
{   
    return 2;
}

这不是:

unsigned int TestClass::TestMethod()
{
    std::vector<unsigned char> vtest;
    vtest.push_back(0xff);

    return 2;
}

错误:

  

错误1错误LNK2019:未解析的外部符号&#34; public:static void   __cdecl std :: _ St​​ring_base :: _ Xran(void)&#34;函数&#34; public:class中引用的(?_Xran @ _String_base @std @@ SAXXZ)   的std :: basic_string的,类   std :: allocator&gt; &安培; __thiscall std :: basic_string,class std :: allocator&gt; :: assign(class   的std :: basic_string的,类   std :: allocator&gt; const&amp;,unsigned int,unsigned int)&#34;   (?分配@?$ basic_string的@ DU?$ char_traits @ d @ @@ STD V'$分配器@ d @ @@ 2 STD @@ @ QAEAAV12 @ ABV12 II @ Z)

RT lib设置为/ MT且禁用程序优化(/ GL)。

有什么方法可以解决这个问题吗?

感谢。

3 个答案:

答案 0 :(得分:3)

正如评论中所讨论的,您需要确保:

  • 使用较旧的库没有运行时库不匹配(/MT /MD选项)

  • /GL(即整个计划优化)已停用

答案 1 :(得分:1)

虽然Marco's answer在技术层面上肯定有用,但您对此设计有更深层次的问题:

您不能在静态库的(公共)标头中使用任何std库类型。不是。任何

虽然可能对某些人起作用,但对其他人来说可能会中断,而你会发现零文档或帮助哪些文档可以正常工作。

std::类型在不同平台工具集版本之间(保证是)二进制兼容,因此在任何接口或类成员中使用any将迟早会中断。

以示例:

  1. 这没关系,使用vector完全是内部的:

    unsigned int TestClass::TestMethod()
    {
        std::vector<unsigned char> vtest;
        vtest.push_back(0xff);
    
        return 2;
    }
    
  2. 如果两个平台工具集编译器+选项为矢量对象生成不同的二进制布局,则会在运行时中断

    unsigned int TestClass::Test2(std::vector<unsigned char> const& vparam)
    {
        vparam.push_back(0xff);
    
        return 2;
    }
    
  3. 对于不同的二进制布局,这也会中断:

    class TestClass {
      std::vector<int> m_buffer;
      ...
    };
    
  4. 与DLL相反,静态库的问题当然是接入界面的内容不那么明显(因为没有dllexport或任何东西。)

    请注意,技术问题本身对于DLL与静态LIB完全相同。即,您不能在DLL / LIB的接口中使用任何std类型,至少包括:

    • 班级成员(甚至是私人成员)
    • 函数参数(无论是否传递by-value,by-ref或by-pointer)
    • 函数返回值

答案 2 :(得分:0)

问题解决了:

我创建了一个dll而不是静态库。

还要确保禁用程序优化(/ GL)并检查/ MT / MD选项。

要创建一个dll,我将库的配置类型设置为&#34;动态链接库(.dll)&#34;并在头文件中定义__declspec(dllexport),如:

#define TEST_EXPORT
#ifdef TEST_EXPORT
#define TEST __declspec(dllexport) 
#else
#define TEST __declspec(dllimport) 
#endif


class TestClass
{
public:
    std::string TEST TestMethod(); 
};