Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29234 Discussions

call Python function from Fortran in visual studio

Carlygao
New Contributor I
1,334 Views

Hi,

 

I need to call python functions from Fortran codes using visual studio. The solution from Gemini is listed as below. I followed all steps, but still didn't work. My project folder is attached to this message. Can anyone help me to check what I did wrong? I use 3.11 version of python. I checked the platform info, and it is win32, so I set win32 in visual studio. However, I tried x64, and didn't work either. Thanks.

 

 

Yes, you can call a Python function from a Fortran program in Visual Studio. This is achieved by creating a "bridge" using C that allows the two languages to communicate.

The process involves three main parts:

  1. A Python script with the function you want to call.
  2. A C wrapper that uses the Python C API to load and run the Python function.
  3. A Fortran program that uses the iso_c_binding module to call the C wrapper function.

You then compile and link all these parts together in your Visual Studio project.

 

Step 1: The Python Script

First, create a simple Python script. For this example, we'll make a function that adds two numbers. Save this file as my_module.py and place it in your Visual Studio project directory.

Python

 

# my_module.py

def add_numbers(a, b):
    """This function adds two numbers and returns the result."""
    print("Hello from Python!")
    return a + b

 

Step 2: The C Wrapper

Next, create a C source file that will act as the bridge. This code uses the Python C API to execute the script. Save this file as c_wrapper.c and add it to your Visual Studio project.

This C function, call_python_add, will be callable from Fortran.

C

 

#include <Python.h>

// This is the C function Fortran will call
double __declspec(dllexport) call_python_add(double a, double b) {
    PyObject *pName, *pModule, *pFunc;
    PyObject *pArgs, *pValue;
    double result = 0.0;

// Initialize the Python Interpreter
    Py_Initialize();

// Make sure the current directory is in the Python path
    // so it can find my_module.py
    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path, PyUnicode_FromString("."));

// Import our python script "my_module"
    pName = PyUnicode_FromString("my_module");
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

if (pModule != NULL) {
        // Get the function "add_numbers" from the module
        pFunc = PyObject_GetAttrString(pModule, "add_numbers");

if (pFunc && PyCallable_Check(pFunc)) {
            // Prepare the arguments to pass to the Python function
            pArgs = PyTuple_New(2);
            PyTuple_SetItem(pArgs, 0, PyFloat_FromDouble(a));
            PyTuple_SetItem(pArgs, 1, PyFloat_FromDouble(b));

// Call the Python function
            pValue = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);

if (pValue != NULL) {
                // Convert the result back to a C double
                result = PyFloat_AsDouble(pValue);
                Py_DECREF(pValue);
            } else {
                PyErr_Print();
            }
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    } else {
        PyErr_Print();
    }

// Finalize the Python Interpreter
    Py_Finalize();
    return result;
}

 

Step 3: The Fortran Program

Now, write the main Fortran program. This program defines an INTERFACE to the C function and then calls it. The iso_c_binding module is essential for ensuring data types are compatible between Fortran and C. Save this as main.f90.

Fortran

 

! main.f90
PROGRAM Fortran_Calls_Python
    USE, INTRINSIC :: iso_c_binding
    IMPLICIT NONE

! Define the interface for the C function
    INTERFACE
        FUNCTION call_python_add(a, b) BIND(C, name='call_python_add')
            IMPORT c_double
            REAL(c_double) :: call_python_add
            REAL(c_double), VALUE :: a, b
        END FUNCTION call_python_add
    END INTERFACE

REAL(c_double) :: x, y, z

x = 10.5_c_double
    y = 20.2_c_double

WRITE(*,*) 'Hello from Fortran! Calling Python...'

! Call the C wrapper function, which in turn calls Python
    z = call_python_add(x, y)

WRITE(*,*) 'Back in Fortran. Result from Python is:', z

END PROGRAM Fortran_Calls_Python

 

Step 4: Compiling and Linking in Visual Studio

This is the most critical step. You need to configure your Visual Studio Fortran project to find the Python libraries and headers.

 

 

  • Create Project: Create a new Fortran Console App project in Visual Studio. Add main.f90 and c_wrapper.c to the project's "Source Files".
  • Configure Project Properties: Right-click on your project in the Solution Explorer and go to Properties. Make sure the Configuration (e.g., Debug) and Platform (e.g., x64) match your Python installation.
  • Add Python Include Directory:

 

      • Navigate to Configuration Properties -> Fortran -> General -> Additional Include Directories.
      • Add the path to Python's include folder. (e.g., C:\Python312\include).

 

  • Add Python Library Directory:

 

      • Navigate to Configuration Properties -> Linker -> General -> Additional Library Directories.
      • Add the path to Python's libs folder. (e.g., C:\Python312\libs).

 

  • Link Python Library:

 

      • Navigate to Configuration Properties -> Linker -> Input -> Additional Dependencies.
      • Add the Python library file, which is typically pythonXY.lib (e.g., python312.lib).

 

  • Build and Run:

 

    • Build the solution (Build -> Build Solution).
    • Before running, ensure the Python DLL (e.g., python312.dll) is accessible. You can either:
      • Copy the DLL from your Python installation folder (e.g., C:\Python312\) into your project's output directory (e.g., x64\Debug).
      • OR add the Python installation folder to your system's PATH environment variable.
    • Run the program (Debug -> Start Without Debugging).

You should see output from both the Fortran program and the Python script:

 Hello from Fortran! Calling Python...
 Hello from Python!
 Back in Fortran. Result from Python is:   30.7000000000000

0 Kudos
4 Replies
uha
Novice
1,238 Views

My experience is that it takes a lot of attention to detail to get this to work, but it can be done. What Gemini put together looks about right to me, although I´d separate initialization, actual function call and shutdown, but for an initial test this may not be required.

Unless you use some old intel fortran compiler only 64 bit is supported, so you also need a 64 bit python installation.

What problem do you run into?

0 Kudos
Carlygao
New Contributor I
1,188 Views

The error message is attached in this message. I think the python code is wrapped in c. But I feel the Fortran even didn't find the c code. I am not sure whether I added the C and Fortran codes into the Fortran project in a right way or not.

 

I updated to python 3.13, the latest one. After I checked the machine type,  it is AMD64, so I changed to x64 everywhere in the visual studio.

Thanks,

 

Carly

0 Kudos
jimdempseyatthecove
Honored Contributor III
551 Views

Prepend your function declaration with

extern "C" double __declspec(dllexport) call_python_add(double a, double b)

 

Jim

0 Kudos
uha
Novice
743 Views

The .c source code file needs to be in a C/C++ project, the Fortran compiler cannot compile it. In that C/C++ project make sure the include and lib directories of your python installation are referenced (you did install these with python?). Right click the VS sln and find the project dependencies, select the fortran project and check that it depends on the C/C++ project. Try to build... Very likely you´ll get errors building the C/C++ project, so try to sort these out. Then set up the fortran project so it links to the C/C++ project´s lib file and build. For simplicity I´d build a static C/C++ library initially.

0 Kudos
Reply