- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am sure that my error is a trivial one here, but I am at a loss for what I am doing wrong. I want to test returning a struct from C++ to my Fortran code, but I can't even get the test program to link correctly and I am hoping someone can offer up advice. My test solution was set up in VS2013, with a Fortran program, and a C++ DLL. The C++ is as follows:
// Win32Project1.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
struct interop_type {
int i;
double j;
};
extern "C" {
__declspec(dllexport) interop_type __stdcall _CPP_func(int* arg) {
interop_type ret_val;
ret_val.i = *arg * 4;
ret_val.j = *arg / 2.0;
return ret_val;
}
}
And the Fortran that I want to call this function from is:
program FortranCPPInterop
implicit none
!DEC$ ATTRIBUTES DLLIMPORT, STDCALL, ALIAS: 'CPP_func' :: CPP_func
type inter_op
integer :: i
double precision :: j
end type inter_op
TYPE(inter_op) :: test, CPP_func
test = CPP_func( 3)
print*, test%i
print*, test%j
end program
When I attempt to build, I get the following error:
1>Source1.obj : error LNK2019: unresolved external symbol __imp_CPP_func referenced in function _MAIN__
Now, I have added the library (.lib) file created by the C++ side of the world as a library to be specifically included in the Fortran Linker options, and I have set the additional include paths for libraries in the Linker option to include the containing directory as well. Can someone point to the mistake I am making? Thanks!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found that I needed (or at least, this made it work) an explicit interface definition in the Fortran file. The following works when returning a simple data type:
program FortranCPPInterop
interface
function CPP_func(ARG)
!DEC$ ATTRIBUTES C, DLLIMPORT, ALIAS:'_CPP_func' :: CPP_func
!DEC$ ATTRIBUTES REFERENCE :: ARG
integer :: CPP_func
integer ARG
end function CPP_func
end interface
integer j
j = CPP_func( 3)
print*, j
end program
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the info. We have a Fortran-Calls-C sample that demonstrates the use of BIND and it's installed with the compiler (default location): C:\Program Files (x86)\Intel\Composer XE 2015\Samples\en_US\Fortran\MixedLanguage.zip. Just though I'd mention that in case it helps others as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For your linker error, you indeed needed to link against the .lib created when the C++ DLL was built. As you discovered, use of ATTRIBUTES STDCALL also makes the default pass-by-value, so you needed REFERENCE.
Is there a reason you are using STDCALL? What you have works but it's simpler if you stick to the default calling mechanism. I'll also comment that if you're calling a routine, you don't have to use DLLIMPORT. (A data reference to a DLL does require that.)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page