Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.
27765 Discussions

Loading a Fortran dll from python in visual studio

New Contributor I

I created a blank visual studio (2019 Enterprise, last update as of posting) solution, and then a fortran dll project in it with only one source file containing the following code :



module example
    use iso_c_binding
    implicit none
    subroutine sqr_2d_arr(nd, val) BIND(C, NAME='sqr_2d_arr')
        !DEC$ ATTRIBUTES DLLEXPORT :: sqr_2d_arr
        integer, intent(in) :: nd
        integer, intent(inout) :: val(nd, nd)
        integer :: i, j
        do j = 1, nd
        do i = 1, nd
            val(i, j) = (val(i, j) + val(j, i)) ** 2
    end subroutine sqr_2d_arr
end module example



Compilation went fine.

To compare with the C++ case I also added a C++ dll project to my solution with no code, and compiled it.

I intend to call my fortran DLL from Python, inside VIsual Studio (so I could directly break in the Fortran from the Python etc.)

Hence I created a "python application" project in my solution, even added the path to my fortran dll to the "search paths" of my python project, and added one python source code file with the following solution :



import os

import ctypes as ct
import numpy as np

# import the dll

fortlibcpp = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thecpp.dll")
fortlib = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thefortran.dll")

# setup the data
N = 10
nd = ct.pointer( ct.c_int(N) )          # setup the pointer
pyarr = np.arange(0, N, dtype=int) * 5  # setup the N-long
for i in range(1, N):                   # concatenate columns until it is N x N
    pyarr = np.c_[pyarr, np.arange(0, N, dtype=int) * 5]

# call the function by passing the ctypes pointer using the numpy function:
_ = fortlib.sqr_2d_arr(nd, np.ctypeslib.as_ctypes(pyarr))




And hit F5 to debug.

I did not add the path of the directory containing my C++ DLL and yet the execution of the line



fortlibcpp = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thecpp.dll")



went fine.

The line



fortlib = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thefortran.dll")



though, triggered the following exception :



Could not find module 'path\to\the\directory\contaning\the\fortran\dll\thefortran.dll' (or one of its dependencies). Try using the full path with constructor syntax.
Stack trace:
 >  File "path\to\the\directory\contaning\the\python\source\file\", line 10, in <module> (Current frame)
 >    fortlib = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thefortran.dll")
Loaded 'ctypes'



I did not touch the properties of the Fortran DLL project though, maybe there's something to tweak there that I am missing (nothing of this kind to do on the C++ side though), but I don't know.

Also, the Fortran DLL looks perfectly kosher in dependency walker.

What am I doing wrong ?

[Configuration : Visual Studio 2019 Enterprise 16.10.3 ; the issue I related appears : Intel Parallel Studio 2020 Update 4 and Intel One Api 2021.3 Fortran compiler (classic for the One Api)] 

0 Kudos
1 Solution
New Contributor I

I used Process Monitor with a filter with "process name is 'python.exe'" and "operation is 'CreateFile'" and lauch the python code which showed that libifcoremdd.dll was actively searched with no result ... Hence I added "oneAPI\compiler\2021.3.0\windows\redist\intel64_win\compiler" to the runtime path in the python, which solved my issue ...

View solution in original post

7 Replies
Black Belt

Do you actually have a path named literally as 


located in the working directory? Including the misspelled "contaning" instead of "containing" ?

Usually, strings such as "name_of_your_computer", etc., which one finds in software documentation, are supposed to be replaced with user-supplied strings.


New Contributor I

Nope, I don't ...

I just replaced my original path, for a privacy matter, by these paths for posting here, with a typo in the process.

[Thank you for considering, for the sake of completeness, that I could be completely stupid and copy a "this/is/a/path" mutatis mutandis into code without modyfing it. ;)]

Black Belt

It was because you left that implausible path in the exception report that I asked if you had used the path without appropriate modification. Such slips can be made by any of us when using copy+paste of snippets of code.

New Contributor I

I know, I was just kidding, out of despair because of my problem.

New Contributor I

I used Process Monitor with a filter with "process name is 'python.exe'" and "operation is 'CreateFile'" and lauch the python code which showed that libifcoremdd.dll was actively searched with no result ... Hence I added "oneAPI\compiler\2021.3.0\windows\redist\intel64_win\compiler" to the runtime path in the python, which solved my issue ...

Honored Contributor II

@MattHouston ,


Please see this page at Intel Fortran Reference online.  If you were not already aware, that page might help you gain better insight into the dependencies with Fortran DLLs built with Intel Fortran compiler.

If you are in good control of the whole package management of what you are doing e.g., individual / toy programs or with very, very small teams, etc. with one or a few users if at all only, which is a vast domain of current Fortran use these days, particularly on Windows, you can consider /libs:static option even for your Fortran DLL build which should then allow you to proceed WITHOUT the libifcore*.dll dependency of your DLL during its consumption with other executives whether it be Excel or Python, etc.



New Contributor I

Thank you for the reference, I will look at it but indeed, using a static library could be simpler for me that a dynamic one. (Especially for the cases where I will link to the MKL.)