fortran/c++ mixed language dll not linking

fortran/c++ mixed language dll not linking

I'm making a single dll which starts off in c++, then calls some subroutines in fortran which in turn call a c++ function and when I link it I get:

sbsday.obj : error LNK2001: unresolved external symbol _addsbsoutputrecord
(and it obviously doesn't link)

sbsday is a fortran subroutine and addSbsOutputRecord is a c++ function which has been defined as:
extern "C" void addsbsoutputrecord(char lulc[], int hru, int gis, int sub, int mgt, int mon, double area, double otherValues[]);
in a c++ header file. It also has the necessary interface defined for it in a fortran mod file.

If I make the project an exe instead of a dll then it links properly and works fine. I have tried defining the c++ function "addSbsOutputRecord" several different ways and in several different files (never at the same time though) and it still doesn't work.

Any help would be greatly appreciated.

3 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

You didn't show us Fortran INTERFACE. Since I have to guess, two possible causes come to my mind:

1) !DEC$ATTRIBUTES C implies name mangling: lowercase. However, IIRC in MSVC++ default name mangling is "as-is", so you should probably need an alias. It's unclear from your post whether the name is lowercase in .h and mixed-case in .cpp; I'd suggest keeping declaration (.h) and definition (.cpp) identical

2) Don't forget REFERENCE attribute for lulc[] argument.

Well, this is the way I'd write prototype and caller:

!=.cpp and .h============ 
extern "C" void addSbsOutputRecord(char lulc[], int hru, int gis, int sub, int mgt,  
int mon, double area, double otherValues[]) ; 
   subroutine addSbsOutputRecord(lulc, hru, gis, sub, mgt, mon, area, otherValues) 
   !DEC$ATTRIBUTES C, ALIAS: "_addSbsOutputRecord":: addSbsOutputRecord 
   character(*):: lulc 
   integer:: hru, gis, sub, mgt, mon 
   real(8):: area, otherValues(*) 
   end subroutine 
end interface

Of course, if lulc should be an array of BYTE, not a string, you should declare it as byte:: lulc(*). In that case, REFERENCE is not needed (but doesn't do harm either).



...I'd just add a tip: when in doubt about name exports/imports, open .obj files of caller and callee in a text editor. Although most of it would be garbage, you'd be able to find exact mangling of exported/imported names and conclude where the problem lies.

Leave a Comment

Please sign in to add a comment. Not a member? Join today