诡异编译错误:无法将类型转换为自身(NDI SDK+MSVC环境)
MSVC编译NDI SDK 5代码时出现类型自转换失败的诡异错误
我在使用NDI SDK 5开发时,调用库函数遭遇了非常奇怪的编译错误,开发平台是MSVC。错误提示都是无法将类型转换为自身,完全无法理解原因,搜索后也没找到有效解决方法,求帮助。
相关代码文件
audio.NDI.ixx
export module audio.NDI; export import :finder;
audio.NDI-finder.ixx
export module audio.NDI : finder; #include "Processing.NDI.Lib.h" import <vector>; /** * @brief Encapsulation of ndi finder object */ export class ndi_finder { private: NDIlib_find_instance_t finder; public: /** * @breif constructor with default options * show_local_sources = true; * p_group = nullptr; */ ndi_finder(); /** * @breif constructor with options * @param show the list of NDI sources that are running on the local machine? * @param groups to search in for sources. */ ndi_finder(const bool, const char*); ~ndi_finder(); /** * @breif search for all NDI sources available. * @param search timeout. * @retrun available source list. */ auto find_source(std::size_t) -> std::vector<NDIlib_source_t>; };
audio.NDI-finder.cpp
module; #include "Processing.NDI.Lib.h" module audio.NDI : finder; import <stdexcept>; constexpr auto NDI_TIMEOUT = 1000; ndi_finder::ndi_finder() { NDIlib_find_create_t findCfg{}; finder = NDIlib_find_create_v2(&findCfg); /* a copy of signature : PROCESSINGNDILIB_API NDIlib_find_instance_t NDIlib_find_create_v2(const NDIlib_find_create_t* p_create_settings NDILIB_CPP_DEFAULT_VALUE(NULL)); */ if (!finder)//nullptr in case of failure. throw std::runtime_error("Failed to create NDI finder !"); } ndi_finder::ndi_finder(const bool show_local_sources, const char* p_groups) { NDIlib_find_create_t findCfg; //configure finder findCfg.show_local_sources = show_local_sources; findCfg.p_groups = p_groups; findCfg.p_extra_ips = nullptr; //deprecated feature finder = NDIlib_find_create_v2(&findCfg); if (!finder)//nullptr in case of failure. throw std::runtime_error("Failed to create NDI finder !"); } ndi_finder::~ndi_finder() { NDIlib_find_destroy(finder); /* a copy of signature : PROCESSINGNDILIB_API void NDIlib_find_destroy(NDIlib_find_instance_t p_instance); */ } auto ndi_finder::find_source(std::size_t ndi_timeout) -> std::vector<NDIlib_source_t> { const NDIlib_source_t* sources {}; std::uint32_t source_number {}; bool found {false}; std::size_t ndi_timeout{}; //try to find sources while (!found) { NDIlib_find_wait_for_sources(finder, ndi_timeout); /* a copy of function signature PROCESSINGNDILIB_API bool NDIlib_find_wait_for_sources(NDIlib_find_instance_t p_instance, uint32_t timeout_in_ms); */ sources = NDIlib_find_get_current_sources(finder, &source_number); /* a copy of function signature PROCESSINGNDILIB_API const NDIlib_source_t* NDIlib_find_get_current_sources(NDIlib_find_instance_t p_instance, uint32_t* p_no_sources); */ found = true; } if (source_number == 0) throw std::runtime_error("No source found."); else { std::vector<NDIlib_source_t> sources_found(sources, sources + source_number); return sources_found; } }
编译错误信息
Error C2440 '=': cannot convert from 'NDIlib_find_instance_t' to 'NDIlib_find_instance_t' Error C2440 '=': cannot convert from 'NDIlib_find_instance_t' to 'NDIlib_find_instance_t' Error C2664 'bool NDIlib_find_wait_for_sources(NDIlib_find_instance_t,uint32_t)': cannot convert argument 1 from 'NDIlib_find_instance_t' to 'NDIlib_find_instance_t' Error C2664 'const NDIlib_source_t *NDIlib_find_get_current_sources(NDIlib_find_instance_t,uint32_t *)': cannot convert argument 1 from 'NDIlib_find_instance_t' to 'NDIlib_find_instance_t' Error C2664 'void NDIlib_find_destroy(NDIlib_find_instance_t)': cannot convert argument 1 from 'NDIlib_find_instance_t' to 'NDIlib_find_instance_t'
可能的原因及解决方案
这种“类型无法转换为自身”的错误,在MSVC的模块代码中通常是由于同一类型被多次定义在不同的模块单元中,导致编译器认为它们是不同的类型。具体到你的情况:
头文件重复包含导致类型不一致
- 你在
audio.NDI-finder.ixx和audio.NDI-finder.cpp的全局模块片段中都包含了Processing.NDI.Lib.h。在C++模块中,全局模块片段的头文件包含和模块单元中的包含可能会导致类型被实例化在不同的上下文,引发类型不匹配。 - 解决方法:只在全局模块片段中包含
Processing.NDI.Lib.h,或者确保所有使用NDI类型的模块单元都通过同一个路径包含头文件,避免宏定义差异导致类型定义变化。
- 你在
NDI SDK的宏定义差异
- NDI SDK的头文件可能根据编译宏(比如
NDILIB_CPP、PROCESSINGNDILIB_EXPORTS等)生成不同的类型定义。如果模块单元和全局模块片段的宏定义不一致,会导致NDIlib_find_instance_t的实际类型不同。 - 解决方法:检查项目的预编译宏设置,确保所有模块单元和全局模块片段使用相同的NDI相关宏定义。比如在项目属性中统一添加
NDILIB_CPP=1等必要宏。
- NDI SDK的头文件可能根据编译宏(比如
模块接口实现的类型可见性问题
- 在模块接口单元(
.ixx)中包含头文件,而在实现单元的全局模块片段中再次包含,可能导致类型的链接期可见性冲突。 - 解决方法:将
#include "Processing.NDI.Lib.h"移到全局模块片段(module;之后),并确保接口单元通过模块导入而非直接包含头文件来使用类型。或者在接口单元中使用import <Processing.NDI.Lib.h>;(如果NDI SDK支持模块导入,不过通常C SDK头文件需要用全局模块片段包含)。
- 在模块接口单元(
另外,你的find_source函数中有一个局部变量ndi_timeout重新定义了参数,这会导致参数被覆盖,运行时使用的是未初始化的局部变量,建议删除这个局部定义:
// 删掉这行 std::size_t ndi_timeout{};
内容的提问来源于stack exchange,提问作者hu4nghe
相关产品推荐
相关产品推荐

