- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to compile a simple code in Fortran that calls a C++ function which gives the value of two reals. To do so, I have followed the steps:
1. Open an empty console project in C++, add a .h and .cpp files.
(file.h)
#pragma once
#if __cplusplus
extern "C"
{
_declspec(dllexport) void change_(float* a, float* b);
}
#endif
(.cpp)
#include "file.h"
#include <iostream>
#include <stdio.h>
extern "C" void change_(float* a, float* b) {
*a = 5.0;
*b = 6.0;
}
2. Change the project to a .dll type in order to compile it, .lib and .dll were generated.
3. Open a new empty console project in Fortran and add the main code.
(.f90)
program fprog
real a,b
a=1.0
b=2.0
print*,'Fortran variables:'
print*,'a=',a
print*,'b=',b
call change(a,b)
print*,'C++ variables:'
print*,'a=',a
print*,'b=',b
stop
end
3. Add the .lib into the source foulder, select the dependency between both projects and compile it, but I get linkage errors.
error LNK2019: unresolved exernal symbol CHANGE which was referred in the funci¢n MAIN__
fatal error LNK1120: 1 unresolved externals
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not so good at fortran interfaces, but one problem I see is in the dll:
// cxdll.h
#ifdef CXDLL_EXPORTS
#define CXDLL_API __declspec(dllexport)
#else
#define CXDLL_API __declspec(dllimport)
#endif
// This class is exported from the dll
extern "C" CXDLL_API void change(float *, float *);
//cxdll.cpp
// cxdll.cpp : Defines the exported functions for the DLL.
//
#include "pch.h"
#include "framework.h"
#include "cxdll.h"
#ifdef __cplusplus
extern "C" {
#endif
// This is an example of an exported function.
CXDLL_API void change(float* a, float* b) {
*a = 5.0;
*b = 6.0;
}
#ifdef __cplusplus
}
#endif
and in fortran:
program fcxdll
implicit none
interface
subroutine change (f1, f2) BIND(C, name='change')
use, intrinsic :: ISO_C_BINDING
implicit none
type (real) :: f1
type (real) :: f2
end subroutine change
end interface
! Variables
real a,b
a=1.0
b=2.0
! Body of fcxdll
print*,'Fortran variables:'
print*,'a=',a
print*,'b=',b
call change(a,b)
print*,'C++ variables:'
print*,'a=',a
print*,'b=',b
stop
end program fcxdll
I was using VS2019 and had to put some thngs in fortran project for pre link event:
Additional Dependencies .\$(PlatformName)\$(ConfigurationName)\cxdll.lib
and
Build Events->Pre-Link Event copy ..\$(PlatformName)\$(ConfigurationName)\cxdll.* .\$(PlatformName)\$(ConfigurationName)
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The name decoration for Fortran external names is compiler-dependent. You seem to be using the conventions of GFortran in your source code, but you are using Ifort to compile.
Change the name in the C file from change_ to CHANGE .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not so good at fortran interfaces, but one problem I see is in the dll:
// cxdll.h
#ifdef CXDLL_EXPORTS
#define CXDLL_API __declspec(dllexport)
#else
#define CXDLL_API __declspec(dllimport)
#endif
// This class is exported from the dll
extern "C" CXDLL_API void change(float *, float *);
//cxdll.cpp
// cxdll.cpp : Defines the exported functions for the DLL.
//
#include "pch.h"
#include "framework.h"
#include "cxdll.h"
#ifdef __cplusplus
extern "C" {
#endif
// This is an example of an exported function.
CXDLL_API void change(float* a, float* b) {
*a = 5.0;
*b = 6.0;
}
#ifdef __cplusplus
}
#endif
and in fortran:
program fcxdll
implicit none
interface
subroutine change (f1, f2) BIND(C, name='change')
use, intrinsic :: ISO_C_BINDING
implicit none
type (real) :: f1
type (real) :: f2
end subroutine change
end interface
! Variables
real a,b
a=1.0
b=2.0
! Body of fcxdll
print*,'Fortran variables:'
print*,'a=',a
print*,'b=',b
call change(a,b)
print*,'C++ variables:'
print*,'a=',a
print*,'b=',b
stop
end program fcxdll
I was using VS2019 and had to put some thngs in fortran project for pre link event:
Additional Dependencies .\$(PlatformName)\$(ConfigurationName)\cxdll.lib
and
Build Events->Pre-Link Event copy ..\$(PlatformName)\$(ConfigurationName)\cxdll.* .\$(PlatformName)\$(ConfigurationName)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your answers, it worked by changing the function name from change_ to change and adding the Bind C interface into the main Fortran code.
In addition, I had to move the dll to the executabe foulder to make it accesible and set the Fortran project as startup one, if not I was getting a message window saying that the .dll is not a Win32 valid application.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page