用Mingw创建静态库链接到VS2008项目?

时间:2012-01-06 14:09:14

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

我想做什么? ...

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

因此,简单的示例文件是......

test.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中:“属性 - &gt;链接器 - &gt;常规 - &gt;其他库目录”我添加了以前创建的库的路径,并在“属性 - &gt;链接器 - &gt;输入 - >中;附加依赖项“我添加了”libtest.a“文件。 当我构建项目时,comile和链接是正常的,exe文件生成,但是当我尝试运行exe ...时发生了segmentatin故障(是的,“libtest.dll”与.exe文件在同一文件夹中)! 我不知道为什么? “__stdcall”在代码中使用,因此在堆栈上推送东西应该没有问题......

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

感谢您的回答。你的建议给了我很多帮助! 我们现在看看解决方案...... 所有的拳头,部分是我的desultoriness ...我只是“忘了”检查在任何情况下.exe在调试模式下在VS2008中bulid时工作。答案是肯定的。 :)所以,在调试模式下,上面的例子效果很好!但仍然无法在发布模式下工作。好吧,这里也是Release模式的解决方案:在VS2008项目保护中设置Linker - &gt; Optimization-&gt;引用 No(/ OPT:NOREF)。这都是......

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

我探索了由vc,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,请改用它。