【发布时间】:2011-03-02 03:57:05
【问题描述】:
我正在从一组静态库构建一个 DLL,但我遇到了一个问题,即只导出了部分类。
我正在做的是声明我要使用预处理器定义导出的所有符号,例如:
#if defined(MYPROJ_BUILD_DLL)
//Build as a DLL
# define MY_API __declspec(dllexport)
#elif defined(MYPROJ_USE_DLL)
//Use as a DLL
# define MY_API __declspec(dllimport)
#else
//Build or use as a static lib
# define MY_API
#endif
例如:
class MY_API Foo{
...
}
然后我使用 MYPROJ_BUILD_DLL 和 MYPROJ_USE_DLL undefined 构建静态库,导致构建静态库。
在另一个构建中,我从这些静态库创建了一个 DLL。所以我定义了MYPROJ_BUILD_DLL,导致我要导出的所有符号都带有__declspec(dllexport) 的属性(这是通过在 DLL 项目源文件中包含所有静态库头来完成的)。
编辑:
关于未引用符号的注意事项:链接器选项保留未引用数据 (/OPT:NOREF) 和不删除冗余 COMDAT (/OPT:NOICF) 已设置为不会删除未引用符号。
好的,现在解决问题。当我使用这个新的 DLL 时,我得到了无法解析的外部,因为并非一个类的所有符号都被导出。例如在这样的类中:
class MY_API Foo{
public:
Foo(char const* );
int bar();
private:
Foo( char const*, char const* );
};
仅导出 Foo::Foo( char const*, char const*); 和 int Foo::bar();。这个怎么可能?我可以理解是否整个班级都失踪了,例如我忘记在 DLL-build 中包含标题。但这只是部分缺失。
另外,如果Foo::Foo( char const*) 没有实现;那么 DLL 构建将有未解决的外部错误。但是构建很好(我还仔细检查了没有实现的声明)。
注意:我正在组合的静态库的组合大小在 30MB 左右,生成的 DLL 为 1.2MB。
我正在使用 Visual Studio 9.0 (2008) 来构建一切。 Depends 检查导出的符号。
编辑: 对于那些想知道为什么我不只是从每个静态库构建 DLL 的人:我不能,因为它们相互交叉引用(这就是为什么我需要将它们组合到一个 DLL 中)。我知道,这太可怕了,我无法真正理解其背后的逻辑。
【问题讨论】:
-
我们(或至少我)建议您获取静态库的所有源代码,并将其添加到单个 DLL 项目中,然后构建一个 DLL。如果可能,完全删除中间 LIB。拥有一个 DLL,以及所有使用驻留在您的 LIB/LIB 中的源文件。
标签: c++ windows visual-studio-2008 dll