如何从DLL / XLL中的Fortran调用C函数

时间:2017-01-27 01:59:21

标签: c++ excel fortran gfortran fortran-iso-c-binding

我想分享如何在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

0 个答案:

没有答案