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

fortran calling C, more unresolved external

Brian_Murphy
New Contributor II
1,282 Views

I thought I had this figured out, but I'm once again having trouble calling a c++ dll from a fortran dll.  I had it working, I think, but not now.  I am blind to whatever I'm doing wrong.

In c++ I have the following function definition.  I have confirmed I can call the function from Excel VBA with the argument passed to it by value.

int WINAPI CheckFileProperties(int featureID)

 In fortran I have the following interface for the above C routine.  This must be where my problems is???

	interface
		function CheckFileProperties(featureID) bind(C, name="CheckFileProperties")
			!DEC$ ATTRIBUTES STDCALL :: CheckFileProperties
			!DEC$ ATTRIBUTES VALUE :: featureID
			import
			integer(c_int) :: CheckFileProperties
        	integer(c_int) :: featureID
		end function
	end interface

Building the fortran DLL generates the following error.

error LNK2019: unresolved external symbol _CheckFileProperties@4 referenced in function _CheckKey		CheckKey.obj		

The following is a dumpbin on the LIB file of the c++ DLL.  The LIB has been added to the file list of the fortran DLL.

Dump of file xlroto32.lib

File Type: LIBRARY

     Exports

       ordinal    name

                  ?CallDefl32@@YGFPAPAUtagSAFEARRAY@@0000000N00NNNFFFFFNF@Z (short __stdcall CallDefl32(struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,double,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,double,double,double,short,short,short,short,short,double,short))
                  ?CallEval32@@YGFPAPAUtagSAFEARRAY@@000000000NNNNFFFFFPAPBD@Z (short __stdcall CallEval32(struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,double,double,double,double,short,short,short,short,short,char const * *))
                  ?CallGetVersion32@@YGNN@Z (double __stdcall CallGetVersion32(double))
                  ?CallResp32@@YGFPAPAUtagSAFEARRAY@@0000000000000NNNFFFFFNFPAPA_W@Z (short __stdcall CallResp32(struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,double,double,double,short,short,short,short,short,double,short,wchar_t * *))
                  ?CheckFileProperties@@YGHH@Z (int __stdcall CheckFileProperties(int))
                  ?compute_mode_shape32@@YGFPAPAUtagSAFEARRAY@@00000000NNNNFFFFFNNN@Z (short __stdcall compute_mode_shape32(struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,struct tagSAFEARRAY * *,double,double,double,double,short,short,short,short,short,double,double,double))
                  _SetExcel12EntryPt@4

  Summary

          C6 .debug$S
          14 .idata$2
          14 .idata$3
           4 .idata$4
           4 .idata$5
           E .idata$6

 

0 Kudos
5 Replies
Steve_Lionel
Honored Contributor III
1,269 Views

You need 

extern "C"

before the "int".

0 Kudos
Brian_Murphy
New Contributor II
1,259 Views

Thanks, Steve.  I had that in there, but had taken it out for reasons I don't recall.  Putting it back has fixed this problem, but that naturally makes another popup.  I will start another thread for it if I don't stumble onto a fix.

Murphy's Law is in full effect - the closer you get to finishing something, the more trouble you'll have.

0 Kudos
andrew_4619
Honored Contributor II
1,244 Views
	interface
		function CheckFileProperties(featureID) bind(C, name="CheckFileProperties")
			!DEC$ ATTRIBUTES STDCALL :: CheckFileProperties
			import
			integer(c_int) :: CheckFileProperties
        	integer(c_int), value :: featureID
		end function
	end interface
0 Kudos
Brian_Murphy
New Contributor II
1,231 Views

Andrew,

What you have suggested triggers the same linker error.  If you know it should work, could I be doing something wrong elsewhere?  Could it be a bug in visual studio 2019?

The fact that I can call the C routine from VBA when compiled with or without extern "C" makes me wonder.

I'm also baffled by the absence of the LIB file from the linker command line.  The C DLL's LIB is in the source file project list, and not checked in Project Dependencies.  Yet with extern "C" in the C file, the linker error goes away.

I also just found out that with extern "C" in the C code, I can call the routine from VBA sometimes, and sometimes not as Excel crashes.  It is very inconsistent.

0 Kudos
andrew_4619
Honored Contributor II
1,213 Views

What I wrote has no bearing at all on the linker error. You should not really use the ATTRIBUTE VALUE with bind C.

0 Kudos
Reply