1

我想做什么?...

首先,使用 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

测试.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”。

主文件

#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.一份文件。当我构建项目时,编译和链接正常,生成 exe 文件,但是当我尝试运行 exe 时...发生分段错误(是的,“libtest.dll”与 .exe 文件位于同一文件夹中)!!!我不知道为什么?代码中使用了“__stdcall”,因此将东西推入堆栈应该没有问题......

请问有什么建议吗?

4

3 回答 3

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,请改用它。

于 2014-02-12T09:39:09.423 回答
1

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

于 2012-01-09T14:24:45.320 回答
0

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

于 2012-01-06T15:24:53.883 回答