【问题标题】:With Mingw created static library link into VS2008 project?用 Mingw 创建静态库链接到 VS2008 项目?
【发布时间】:2012-02-04 06:07:55
【问题描述】:

我想做什么? ...

首先,使用 MinGW 的 g++ 编译器创建静态库。

所以,简单的示例文件是...

测试.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <iostream>

#ifdef __cplusplus
extern "C" {
#endif

#ifdef EXPORT_DLL_FUNCT
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

    DLL_API void __stdcall whatever( int a, int b );   

#ifdef __cplusplus
}
#endif

#endif  // EXAMPLE_H

test.cpp

#include "test.h"

__stdcall void whatever( int a, int b ) {
    std::cout << "whatever printout !!!" << std::endl;
    int c = a + b;
}

当我使用编译器命令时:

g++ -c -DEXPORT_DLL_FUNCT test.cpp -o test.o

g++ -shared test.o -o libtest.dll -Wl,--out-implib=libtest.a

文件“libtest.dll”和“libtest.a”被创建。为什么两者都需要?因为,如果你打算在 VS2008 项目(MSVC++)中使用库,这两个文件都是必需的——我在 MinGW 的网站上读到了。

接下来...我创建了 VS2008 Win32 控制台应用程序项目,该项目将从库中调用函数“whatever”。

main.cpp

#include "../mingw/test.h"
#include <iostream>


void main(void)
{
    std::cout << "\n*** start ***" << std::endl;

    whatever(3, 2);

    std::cout << "\n*** end ***" << std::endl;

}

在 VS2008 中:“Properties-->Linker-->General-->Additional Library Directories”我添加了以前创建的库的路径,并在“Properties-->Linker-->Input-->Additional Dependencies”中添加了“libtest.a”文件。 当我构建项目时,编译和链接正常,生成了 exe 文件,但是当我尝试运行 exe 时...发生分段错误(是的,“libtest.dll”与 .exe 文件在同一个文件夹中)!!! 我不知道为什么?代码中使用了“__stdcall”,所以压栈应该没有问题...

有什么建议吗?

【问题讨论】:

    标签: visual-c++ dll mingw static-libraries stdcall


    【解决方案1】:

    虽然 GCC 创建的导入库符合“Archive”标准(.a,或者 .lib 对于 vc),并且归档中的目标文件也符合 COFF 标准,但它不兼容 VC 的方式.

    我探索了vc创建的import library,implib sdk和gcc,发现gcc和implib sdk创建的导入库是一样的。最令人印象深刻的区别是成员(存档中的目标文件)的名称对于 implib sdk 是相同的,而对于 gcc 是不同的。 VC 的链接器不会拒绝与 gcc 的导入库链接,但会生成格式错误的 exe。

    你可以看看 implib sdk,它可以制作一个与 vc 一起工作的导入库。但是有些限制很烦人,比如 dll 的文件名长度、字符集等。

    使用vc的链接器来创建导入库是一个不错的方法。确保创建的导入库与您的源代码兼容。对于你的情况,你可以试一试:

    1. 像这样写一个.def文件

      LIBRARY libtest
      EXPORTS
          whatever@8
      

      将其保存为 libtest.def

    2. 使用链接器制作导入库:

      link /lib /out:libtest.lib /def:libtest.def
      
    3. 现在您有了 libtest.lib,请改用它。

    【讨论】:

      【解决方案2】:

      感谢您的回答。你的建议对我帮助很大! 现在让我们看看解决方案... 首先,部分是我的杂乱无章......我只是“忘记”检查在调试模式下在VS2008中构建时.exe是否在任何情况下工作。答案是肯定的。 :) 所以,在调试模式下,上面的例子运行良好!但在发布模式下仍然不起作用。好吧,这里也是发布模式的解决方案:在 VS2008 项目属性中设置 Linker-->Optimization->References to No(/OPT:NOREF)。就是这样……

      【讨论】:

        【解决方案3】:

        对此我没有很好的解释,但是在 VS 2010 中,如果我在 VS 编译行中添加了 /Zi/ZI/Z7(所有启用调试符号的选项),应用程序就会运行正确并调用 MinGW 库中的函数。我最初认为这意味着 VS 中的优化器导致了问题,但是指定 /Od 并不能防止分段错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-19
          • 2010-10-04
          • 1970-01-01
          • 2020-12-16
          • 1970-01-01
          相关资源
          最近更新 更多