windows DLL 和静态库的相同头文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1089828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:46:49  来源:igfitidea点击:

Same Header File for both DLL and Static Library

c++windows

提问by DeusAduro

So the common (at least VS 2005 states) way to define exports/imports for a DLL is:

因此,为 DLL 定义导出/导入的常见(至少 VS 2005 状态)方法是:

#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif

class MY_API MyClass {
    ...
};

This works great if I'm just building my code as a DLL. However, I want to have the option of using a static library OR a DLL. Now one obvious (but terrible) solution, is to copy all the code, removing the DLL 'MY_API' defines. Now what would seem a much better approach is a command line switch to either define, or not define the DLL stuff. However in the case of a static library what should 'MY_API' be?

如果我只是将我的代码构建为 DLL,这非常有效。但是,我希望可以选择使用静态库或 DLL。现在一个明显(但可怕)的解决方案是复制所有代码,删除 DLL 'MY_API' 定义。现在看起来更好的方法是使用命令行开关来定义或不定义 DLL 内容。但是,在静态库的情况下,“MY_API”应该是什么?

#ifdef DLL_CONFIG
    #ifdef MY_EXPORTS
    #define MY_API __declspec(dllexport)
    #else
    #define MY_API __declspec(dllimport)
    #endif
#else
    #define MY_API // What goes here?
#endif

class MY_API MyClass {
    ...
};

Now assuming that this can be done will there be issues when a user of the library includes the header files (ie. will they have to define 'DLL_CONFIG')?

现在假设可以这样做,当库的用户包含头文件时会出现问题(即,他们是否必须定义“DLL_CONFIG”)?

回答by GManNickG

Nothing.

没有。

Leave it as #define MY_APIand all instances of MY_API will simply vanish.

保持原样#define MY_API,MY_API 的所有实例都会消失。

You can add new build configurations, such as Debug - DLL and Release - DLL that mimic the others except they #define DLL_CONFIG.

您可以添加新的构建配置,例如 Debug-DLL 和 Release-DLL,它们模仿除它们之外的其他配置#define DLL_CONFIG

To clone a configuration, get to the configuration manager (like the drop down of the Debug/Release list box), then under 'Active solution configuration' select new. You can now name it "Debug - DLL" and set Copy Settingsto Debugand now that's left to do is define DLL_CONFIG.

要克隆配置,请访问配置管理器(如调试/发布列表框的下拉菜单),然后在“活动解决方案配置”下选择新的。您现在可以将其命名为“Debug-DLL”并设置Copy SettingsDebug,现在剩下要做的就是定义DLL_CONFIG.

To do this, go to project properties->configuration properties->C/C++->Preprocessor, and type DLL_CONFIGin there. You will also see that's where things like NDEBUGand WIN32are defined.

为此,请转到项目属性->配置属性->C/C++->预处理器,然后DLL_CONFIG在其中键入。您还将看到这就是定义likeNDEBUG和的地方WIN32

Like haffax said, use project specific names. I would recommend something like:

就像haffax 说的那样,使用项目特定的名称。我会推荐类似的东西:

#ifdef THEPROJECT_USE_DLL
    #ifdef THEPROJECT_BUILDING_PROJECT
        #define THEPROJECT_API __declspec(dllexport)
    #else
        #define THEPROJECT_API __declspec(dllimport)
    #endif
#else
    #define THEPROJECT_API
#endif

Now users of your DLL just #define THEPROJECT_USE_DLLif they are using the DLL version, just like your "- DLL" configurations have.

现在你的 DLL 的用户#define THEPROJECT_USE_DLL只要他们使用的是 DLL 版本,就像你的“- DLL”配置一样。

回答by haffax

Just define MY_API as empty. Like this:

只需将 MY_API 定义为空。像这样:

#ifdef DLL_CONFIG
    #ifdef MY_EXPORTS
    #define MY_API __declspec(dllexport)
    #else
    #define MY_API __declspec(dllimport)
    #endif
#else
    #define MY_API
#endif

In case of static linking no declspec is necessary.

在静态链接的情况下,不需要 declspec。

Users of your library will have to define DLL_CONFIGif they want to use it as a dll or not define it if they want to use it as a static library. There won't be any issues as is. This kind of configuration is done in many libraries.

您的库的用户必须定义DLL_CONFIG他们是否要将其用作 dll,或者如果他们想将其用作静态库,则不定义它。不会有任何问题。这种配置在许多库中都有完成。

Edit: Of course you shouldn't use the names MY_EXPORTSand DLL_CONFIGas such. Use project specific prefixes for all of your macros, so that there are no name clashes.

编辑:当然,你不应该使用的名字MY_EXPORTSDLL_CONFIG这样。为所有宏使用项目特定的前缀,以免发生名称冲突。

回答by ralphtheninja

Do nothing. No special calling convention is needed to link against a static library. The only thing you need to do, is to make sure that the linker links with your.lib.

没做什么。链接静态库不需要特殊的调用约定。您唯一需要做的就是确保链接器与 your.lib 链接。