如何在Visual Studio的C程序中调用Dymola生成的FMU动态链接库
解决Dymola生成FMU在VS2022 C项目中调用失败的步骤
1. 先确认FMU的基础兼容性
- 检查Dymola导出FMU的设置:必须选FMI 2.0(别选错1.0或3.0),且架构要和VS项目匹配(Dymola默认输出64位FMU,VS项目就得设为x64,32位同理)。
- 解压FMU后,看
binaries目录下的子文件夹(比如win64)里的.dll,要和你的项目平台完全对应。
2. 核对VS项目的配置细节
- 包含目录:把FMI2头文件(
fmi2.h、fmi2_types.h、fmi2_function.h)所在的文件夹路径,添加到项目属性的C/C++ -> 常规 -> 附加包含目录里。 - 库目录:将FMU解压后
binaries/winXX(XX是32或64)的路径,加到链接器 -> 常规 -> 附加库目录。 - 链接器依赖:如果Dymola没生成对应的
.lib文件,先通过dumpbin /exports 你的FMU.dll导出函数列表,再用lib /def:生成的def文件 /out:你的FMU.lib生成lib,然后把这个lib加到链接器 -> 输入 -> 附加依赖项里。 - 运行时库:Dymola生成FMU默认用
多线程DLL (/MD),VS项目必须同步设置(C/C++ -> 代码生成 -> 运行时库),不然会出现运行时冲突。
3. 按FMI2标准流程排查调用代码
每一步都要检查返回值,别跳过:
#include "fmi2.h" #include <windows.h> // 1. 加载FMU动态库 HINSTANCE hFMU = LoadLibrary(L"绝对路径/你的FMU.dll"); if (!hFMU) { // 加载失败时用GetLastError()查原因,大概率是路径或架构不匹配 DWORD err = GetLastError(); return -1; } // 2. 获取FMI2核心函数指针 fmi2GetVersionTYPE* fmi2GetVersion = (fmi2GetVersionTYPE*)GetProcAddress(hFMU, "fmi2GetVersion"); fmi2InstantiateTYPE* fmi2Instantiate = (fmi2InstantiateTYPE*)GetProcAddress(hFMU, "fmi2Instantiate"); fmi2SetupExperimentTYPE* fmi2SetupExperiment = (fmi2SetupExperimentTYPE*)GetProcAddress(hFMU, "fmi2SetupExperiment"); // 其他必要函数(初始化、步长仿真等)都要确认获取成功,不能为NULL // 3. 实例化模型:modelGuid必须和FMU里modelDescription.xml的guid完全一致 fmi2Component comp = fmi2Instantiate( "test_instance", fmi2CoSimulation, "{这里填modelDescription.xml里的guid字符串}", NULL, 0, NULL, NULL, NULL, NULL ); if (!comp) { // 实例化失败先查guid是否输错,或者FMU本身损坏 return -1; } // 4. 实验设置与初始化 fmi2Status status = fmi2SetupExperiment(comp, 0, 0, 10.0, 1, 0); if (status != fmi2OK) { // 检查起始/结束时间参数是否合理 return -1; } status = fmi2EnterInitializationMode(comp); if (status != fmi2OK) { // 初始化失败可能是模型参数未正确赋值 return -1; } // 5. 循环执行仿真步长 double currentTime = 0.0; const double stepSize = 0.1; while (currentTime < 10.0) { status = fmi2DoStep(comp, currentTime, stepSize, 1); if (status != fmi2OK) { // 步长失败查时间参数或模型本身稳定性 return -1; } currentTime += stepSize; // 读取模型变量:variable_reference要从modelDescription.xml里找对应变量的编号 fmi2Real outputValue; status = fmi2GetReal(comp, &variable_reference, 1, &outputValue); }
- 重点提示:
modelGuid和variable_reference都要从FMU的modelDescription.xml里精准复制,不能手动瞎填。 - 每次调用FMI2函数后,若返回
fmi2Error或fmi2Fatal,立刻调用fmi2GetLastError获取具体错误信息,能快速定位问题。
4. 避开常见的坑
- 用绝对路径加载dll,或者把dll直接放到VS项目的输出目录(比如
Debug/x64),避免路径解析失败。 - 别用中文路径,Windows下宽字符路径也尽量避开特殊字符。
- 先在Dymola里把原模型仿真通,确认模型本身没问题再生成FMU——模型有错误的话,FMU肯定调用失败。
- 如果FMU依赖外部数据文件,要把文件放到程序能访问的路径下。
内容的提问来源于stack exchange,提问作者Vaskebjornus
相关产品推荐
相关产品推荐

