我想做什么? ...
首先,使用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”在代码中使用,因此在堆栈上推送东西应该没有问题......
有什么建议吗?
答案 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的链接器创建导入库是一种好方法。确保创建的导入库与源代码兼容。根据您的情况,您可以尝试一下:
写一个像这样的.def文件
LIBRARY libtest
EXPORTS
whatever@8
将其另存为libtest.def
使用链接器创建导入库:
link /lib /out:libtest.lib /def:libtest.def
现在你有了libtest.lib,请改用它。