c++ - 使用 MinGW 和 wclang 交叉编译 DLL 时,我真的需要 __declspec(dllexport) 吗?

标签 c++ dll mingw

这里有类似的问题,但他们并没有完全回答我的问题:

当我使用 MinGW 和 wclang 从 Mac OS X 交叉编译 DLL 时,为什么我的 DLL 在不使用 __declspec 的情况下也能正常工作?

MinGW DLL sample docs ,以及我看到的每一个引用,都说在函数声明之前使用 __declspec(dllexport) 。然而,我的 9,000 行库中的代码没有使用它,而且 DLL 工作得很好!

例如,这是一个以相同方式构建的人为示例库:

#include <stdio.h>

extern "C" {

int hello(const char* name) {
  printf("Hello, %s!\n", name);
  return 0;
}

}

在 Mac OS X 10.10.3 上用这个编译:

w32-clang++ test.cpp -shared -o test.dll

生成一个漂亮的 DLL:

enter image description here

还有我的 Windows 应用程序:

#include "stdafx.h"
#include <Windows.h>
#include <iostream>

typedef int(*hellofn)(const char*);

int _tmain(int argc, _TCHAR* argv[])
{
  DWORD err;

  HINSTANCE dll = LoadLibrary(L"E:\\test.dll");
  if (!dll) {
    err = GetLastError();
    std::cout << "Can't load library: " << err << std::endl;
    return 1;
  }

  hellofn hello = (hellofn)GetProcAddress(dll, "hello");
  if (!hello) {
    err = GetLastError();
    std::cout << "Could not load the function: " << err << std::endl;
    return 2;
  }

  int ret = hello("nerd");
  std::cout << "hello() returned " << ret << std::endl;

  return 0;
}

效果很好:

enter image description here

我是在搬起石头砸自己的脚,还是有什么我没有看到的魔法?我在想 wclang (MinGW+clang) 知道以某种方式自动使用 __stdcall 并且不会破坏函数名称?

最佳答案

不,在使用 MinGW 构建 DLL 时,您不需要 __declspec(dllexport); (事实上​​ ,我自己经常省略它)。需要注意的是,如果只有一个要包含在 DLL 中的符号被如此修饰,那么您希望导出的所有其他符号必须同样被修饰,(除非您通过 --export -all-symbols 构建 DLL 时链接器的选项)。

如果您包含仅未修饰的 符号,那么将导出所有全局符号,就像默认指定了--export-all-symbols 一样。

但是,这与 __stdcall vs. __cdecl 调用约定或名称修改没有任何关系;它只是 DLL 导出表中符号可见性的决定因素。如果您没有将函数声明为 __stdcall__cdecl,那么它们将默认为 __cdecl;这没问题,前提是提供 DLL 和调用者都同意该约定。同样,如果两者都同意任何名称修改约定(这通常意味着,特别是在 C++ 的情况下,它们在构建时都使用相同的编译器),那么就不会有链接问题。

关于c++ - 使用 MinGW 和 wclang 交叉编译 DLL 时,我真的需要 __declspec(dllexport) 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30114671/

相关文章:

c++ - std::system似乎没有运行我的命令

c++ - 无法引用嵌套在模板参数中的模板名称

c++ - 编译错误/usr/bin/ld : cannot open output file bin/server: No such file or directory

c# - 在 C# 中将资源 (XML) 添加到 DLL

qt - 尝试将Qt应用程序与我的静态库链接时存在 undefined reference

c++ - 添加到 vector 或从 vector 中删除后,指向 vector 元素的指针是否保留(在 C++ 中)

c++ - Visual Studio 2010 和 MinGW

dll - 什么是 *.dll.s 文件以及它们的用途是什么?

c++ - 尽管已安装,但在 MinGW 中未找到 gtkmm

mingw - 有人知道www.mingw.org的状态吗?