关于Windows上DLL导出/导入和外部的问题

时间:2009-09-17 19:35:33

标签: c++ dll shared-libraries

嘿伙计们我在windows dll上有一些简单的问题。

基本上我使用ifdef来处理dllexport和dllimport,我的问题实际上是关于dllexports和dllimports以及extern关键字的位置。

我将dllimports / dllexports放在头文件上但是我必须将dllexport和dllimports放在实际定义上吗?

typedef怎么样?

我把dllimport / dllexport放在前面吗?如在

dllexport typedef map<string, int> st_map

关于extern关键字,我看到它的使用方式如下:

extern "C" {

dllexport void func1();

}

我也看到它被这样使用:

extern dllexport func1();

一个包括“C”而另一个没有,我的问题是有什么区别我需要使用它吗?如果我这样做,那么我是否将它用于dllexport和dllimport我是否必须在头文件声明和定义上使用它?

我的项目将成为共享库,它包含几个我要导出的类文件,一些我要导出的typdef和一些全局函数,我也想将它们全部导出到一个dll中。

有人请你开心吗?

编辑:

好吧我想我会发布一些我已经完成的小提取物,还注意到我正在为linux和windows构建库,所以我做了检查:

mydll.h

#ifdef WINDOWS
#   ifdef PSTRUCT_EXPORT
#   define WINLIB __declspec(dllexport)
#   else
#   define WINLIB __declspec(dllimport)
#   endif
#else
#  define WINLIB
#endif

WINLIB void funct1();

现在在源代码中:

mydll.cpp

#define PSTRUCT_EXPORT

void funct1() <---- do i need to add WINLIB in front of it? 
                      Or is doing it in the header enough?

2 个答案:

答案 0 :(得分:7)

首先,您不需要导入或导出typedef。只要它们在双方使用的头文件中,你就是好的。您需要导入/导出函数和类定义。

大概你对导入和导出代码使用相同的头文件,所以你可以做一些makefile魔术来定义每一面的预处理器宏,然后做这样的事情:

#if defined( LIBRARY_CODE )
#define MYAPI __declspec(dllexport)
#else
#define MYAPI __declspec(dllimport)
#endif

extern MYAPI void func1();
class MYAPI MyClass {
    ...
};

关于C与C ++函数,您可以这样做:

#if defined( __cplusplus__ ) // always defined by C++ compilers, never by C
#define _croutine "C"
#else
#define _croutine
#endif

extern _croutine void function_with_c_linkage();

确保从C ++源文件(包含此函数的实现)导入此头文件,否则编译器将不知道为其提供C链接。

答案 1 :(得分:2)

  1. typedef不需要dllimport / dllexport,它只是一个定义
  2. dllimport / dllexport不标准,考虑为其他平台/编译器定义宏
  3. 还会处理调用约定(cdecl,stdcall,...),否则你会遇到问题(如果你需要与Visual Basic互操作使用stdcall)
  4. 包含在extern“C”中,以便可以在C ++程序中使用lib,使用#ifdef __cplusplus使其仅对C ++可见。
  5. 查看不同的OpenSource库。在那里你会找到很多关于如何制作一个好的库标题的例子。在没有extern“C”的C ++的情况下,名称修饰可能存在问题。