我想分享如何在DLL / XLL中调用Fortran中的C / C ++函数。实际上我正在编写一个Excel XLL项目来解决Excel中的方程式。我接下来的步骤是实现Simplex,root查找和Fortran中的其他函数,以便通过XLL而不是DLL在Excel中调用。
我正在使用VS2015在Code :: Blocks中制作XLL(C ++)和gfortran来编译Fortran代码。
你需要使用gfortran / Mingw中的以下一组库来链接VS2015 C ++中的代码:我在VS2015中使用文件.a而不是.lib,它不会导致问题::
libgcc.a, libgfortran.a, libmingwex.a, libmsvcrt.a, libpthread.a, libquadmath.a
C ++代码:
prototypes:
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*pF_arg2)(double, double &);
double externo(pF_arg2 cfunk, double x);
void dobraC(double x, double &y); // call-back function
#ifdef __cplusplus
}
#endif
void dobraC(double x, double &y) // call-back function
{
y = x * 2;
}
__declspec(dllexport) double Dobra2x(double arg) // Fortran Interop
{
double x, y;
try
{
x = arg;
y = externo(&dobraC, x);
}
catch (...)
{
}
return y;
}
Fortran / GFortran代码如下:
real(c_double) FUNCTION externo(cfunk, x) bind(c, name = "externo")
use iso_c_binding
implicit none
! Define interface of call-back routine.
ABSTRACT INTERFACE
SUBROUTINE callback (x, y)
USE, INTRINSIC :: ISO_C_BINDING
REAL(KIND=C_DOUBLE), INTENT(IN), VALUE :: x
REAL(KIND=C_DOUBLE), INTENT(OUT) :: y
END SUBROUTINE callback
END INTERFACE
REAL(KIND=C_DOUBLE), INTENT(IN), VALUE :: x
REAL(KIND=C_DOUBLE) :: y
TYPE(C_FUNPTR), INTENT(IN), VALUE :: cfunk
PROCEDURE(callback), POINTER :: funk
! Convert C to Fortran procedure pointer.
CALL C_F_PROCPOINTER (cfunk, funk)
! Call it.
CALL funk(x, y)
externo = y
END FUNCTION externo