我在同一个Visual Studio解决方案中有2个C++项目:Engine
,一个库;Test
,使用Engine
库
Engine
在Windows上正确编译并生成库和dll。库也正确地提供给Test
的链接器
在Test
中,我尝试从Engine
导入模块,但编译器失败并显示错误C2230
以下是 2 个项目的代码摘录:
Engine
>哈尔·
export module hal;
#ifdef TEST_ENGINE_EXPORTS
#define TEST_ENGINE_API __declspec(dllexport)
#else
#define TEST_ENGINE_API __declspec(dllimport)
#endif
import <string>;
export extern TEST_ENGINE_API void prepareMain();
export extern TEST_ENGINE_API int init();
//...
Test
>主要.cpp
#include <cstddef>
#include <stdio.h>
import hal; //fails here: error C2230 could not find module 'hal'
int main(int argc, char const* argv[])
{
prepareMain();
// some other stuff...
}
我使用的是 Visual Studio 2022(v. 17.4.0),对于这两个项目,我使用 std::c++latest、/permissive- 和/experimental:module 进行编译。我还将Engine
标头的文件夹添加为Test
项目的附加包含目录。 我试图完全删除该模块,并在Test
中包含头文件,并正确调用函数
我已经阅读了这个问题(如何从另一个库导入c ++模块?),它与我有相同的问题,以及一条评论中链接的文章(VS2019模块),但我看不到它如何解决我的问题
编辑
所以,我运行了几个测试,基本上,这似乎源于我的库是一个dll项目的事实
。我尝试用 2 个项目制作一个新解决方案
库是一个WindowsStaticLib项目。编译器选项有:/std:c++latest
、/std:c17
、/permissive-
、/experimental:module
、/sdl
和/W3
(最后 2 个默认存在,我让它们保持原样)。我停用了预编译标头,因为它似乎干扰了模块(使用/exportHeader
编译模块单元,因为当模块导入标准标头导致 VS 开始在标头中查找 pch.h 时,此处建议这样做)
对于使用库的实际项目;库项目作为参考添加,编译器选项与库项目相同,lib 标头目录添加到 VC++ 目录>外部包含目录,lib 文件夹添加到库目录,.lib 文件作为附加依赖项添加
一切正常。 模块被正确找到并导入,并且可以从实际项目中调用函数。 作为旁注,我应该补充一点,我不需要将我的模块函数指定为extern
,以便它们可以在其他项目main.cpp
中使用。我以为我应该这样做,但显然没有。
现在我尝试做同样的事情,但使用库的 DLL 项目。具有 2 个项目的新解决方案,其配置与以前的解决方案完全相同。 当我尝试在实际项目main.cpp
中导入模块时出现错误 C2230。
有谁知道这件事吗? 是我只是不知道的正常行为吗?
MSVC Dll 具有 C++20 个模块可用。确保两件事:
- 要导出的项目要么是 dll 导出的,例如
export __declspec(dllexport) int FunctionInDllExample(int x);
或
导出自导出文件(.def 文件)。 - 在项目属性中:"VC++ 目录"->"所有模块都是公共的"设置为"是"。
我已经测试过从 dll 中的 C++20 模块导出 dll 可以正常工作。
模块定义(导出)文件的参考:
https://learn.microsoft.com/en-us/cpp/build/reference/module-definition-dot-def-files?view=msvc-170
("模块定义文件"中的术语"模块"不是指C++20模块,因为.def文件已经使用了几十年。所以不要对此感到困惑。[然而,术语"模块"可能是C++20个模块的前身。