尝试使用 gcc 编译用 C 编写的简单 dll 失败

Cas*_*ion 3 c dll gcc declspec

尝试使用 gcc 编译一个用 C 编写的简单 DLL。

尝试遵循许多教程,但即使我将文件精简到最基本的内容,也无法编译它。

test_dll.c

#include <stdio.h>

__declspec(dllexport) int __stdcall hello() {
    printf ("Hello World!\n");
}
Run Code Online (Sandbox Code Playgroud)

尝试使用命令编译它

gcc -c test_dll.c
Run Code Online (Sandbox Code Playgroud)

失败,得到这个输出

test_dll.c: In function '__declspec':
test_dll.c:3:37: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'hello'
 __declspec(dllexport) int __stdcall hello() {
                                     ^
test_dll.c:5:1: error: expected '{' at end of input
 }
 ^
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会版本

gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
Run Code Online (Sandbox Code Playgroud)

小智 6

这取决于您想要做什么:

1.在linux上构建linux的库

然后删除__declspec(dllexport)__stdcall。在 Linux 上,构建库的源代码不需要任何特殊内容。请注意,库在 Linux 上不是 DLL,它们被命名为*.so(共享对象)。您必须编译-fPIC并链接-shared才能创建.so文件。请使用谷歌了解更多详细信息。

2.在linux上构建windows DLL

安装 mingw 包(在包管理器中搜索它们)。然后,不只是gcc调用针对 windows/mingw 的交叉编译器,例如i686-w64-mingw32-gcc

3.允许跨平台构建库,包括Windows

如果您希望能够在 Windows 和 Linux 上使用相同的代码构建库,则需要一些预处理器魔法,因此__declespec()仅在针对 Windows 时使用。我通常使用这样的东西:

#undef my___cdecl
#undef SOEXPORT
#undef SOLOCAL
#undef DECLEXPORT

#ifdef __cplusplus
#  define my___cdecl extern "C"
#else
#  define my___cdecl
#endif

#ifndef __GNUC__
#  define __attribute__(x)
#endif

#ifdef _WIN32
#  define SOEXPORT my___cdecl __declspec(dllexport)
#  define SOLOCAL
#else
#  define DECLEXPORT my___cdecl
#  if __GNUC__ >= 4
#    define SOEXPORT my___cdecl __attribute__((visibility("default")))
#    define SOLOCAL __attribute__((visibility("hidden")))
#  else
#    define SOEXPORT my___cdecl
#    define SOLOCAL
#  endif
#endif

#ifdef _WIN32
#  undef DECLEXPORT
#  ifdef BUILDING_MYLIB
#    define DECLEXPORT __declspec(dllexport)
#  else
#    ifdef MYLIB_STATIC
#      define DECLEXPORT my___cdecl
#    else
#      define DECLEXPORT my___cdecl __declspec(dllimport)
#    endif
#  endif
#endif
Run Code Online (Sandbox Code Playgroud)

DECLEXPORT然后在要由库导出的每个声明前面和SOEXPORT每个定义前面放置。这只是一个简单的例子。