调试项目过程发现,在使用控制台应用项目调用sundials能够直接运行,但是改为静态链接库项目时,就出现了无法识别的外部符号问题,LNK2019。
查找发现,项目可以识别函数的名称,但是却没有定义;原因是无法找到lib和dll文件
因此需要将lib文件直接附加进来;
同时dll文件也直接复制到项目的工程文件中;
由于我是使用fortran主程序调用c++的静态链接库,所以dll文件放在了fortran的项目下面
详细测试代码如下:
fortran 主程序:
implicit none
interface
subroutine solve_ode() bind(C, name="solve_ode")
end subroutine solve_ode
end interface
call solve_ode()
end program call_cpp_solver
c++静态链接库:
#include "pch.h"
// ExampleLib.cpp
#include <iostream>
#include <cvode/cvode.h> // 包含SUNDIALS的CVODE库
#include <nvector/nvector_serial.h> // 用于序列向量操作
#include <sunmatrix/sunmatrix_dense.h> // 密集矩阵操作
#include <sunlinsol/sunlinsol_dense.h> // 密集线性求解器
#include <cvode/cvode_direct.h> // CVODE直接方法求解器
#include <sundials/sundials_types.h> // 定义SUNDIALS的类型
// 简单的微分方程函数 dy/dt = -ky
static int f(realtype t, N_Vector y, N_Vector ydot, void* user_data) {
realtype k = *(realtype*)user_data;
NV_Ith_S(ydot, 0) = -k * NV_Ith_S(y, 0);
return 0;
}
extern "C" {
void solve_ode() {
SUNContext sunctx;
SUNContext_Create(NULL, &sunctx);
realtype t0 = 0.0, t = 1.0, dt = 0.1, k = 0.1;
N_Vector y = N_VNew_Serial(1, sunctx);
NV_Ith_S(y, 0) = 1.0; // 初始条件
void* cvode_mem = CVodeCreate(CV_ADAMS, sunctx);
CVodeInit(cvode_mem, f, t0, y);
CVodeSStolerances(cvode_mem, 1e-4, 1e-4);
CVodeSetUserData(cvode_mem, &k);
SUNMatrix A = SUNDenseMatrix(1, 1, sunctx);
SUNLinearSolver LS = SUNLinSol_Dense(y, A, sunctx);
CVodeSetLinearSolver(cvode_mem, LS, A);
while (t < 10) {
CVode(cvode_mem, t, y, &t, CV_NORMAL);
std::cout << "At t = " << t << ", y = " << NV_Ith_S(y, 0) << std::endl;
t += dt;
}
// 清理
N_VDestroy(y);
CVodeFree(&cvode_mem);
SUNMatDestroy(A);
SUNLinSolFree(LS);
}
}