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

Linker Errors when using STDCALL

Vippis
Beginner
442 Views

Hi there,

Im trying to compile a programm .exe as a .dll to use it in a python script using ctypes. After making the adjustments to the program (variables structs for phyton, bind ctype functions), I complied the programm as a .dll. Unfortunately, ctypes was unable to detect the "binded" functions. After some research, I assumed, this must be related to the External Procedures of the project. I changed the External Procedures to STDCALL for this instance.

About the structure of the program. It includes XML Parser written in c++. The main program depens on the XML parser project. Before changing the External Procedures I was able to compile the .dll or .exe.

I use VS 2015 with the Intel XE Fortran Compiler 2017.

 

So now I get the following errors:

 

Severity	Code	Description	Project	File	Line	Suppression State
Error		error LNK2001: unresolved external symbol _GETCWD@4		Ausgabe_Mnkenn.obj		
Error		error LNK2019: unresolved external symbol _SYSTEM@8 referenced in function _DATEILOESCHEN_MOD_mp_DATEILOESCHEN		DateiLoeschen.obj		
Error		error LNK2019: unresolved external symbol _GETCWD@4 referenced in function _DATEILOESCHEN_MOD_mp_DATEILOESCHEN		DateiLoeschen.obj		
Error		error LNK2001: unresolved external symbol _SYSTEM@8		DateiSchliessen.obj		
Error		error LNK2001: unresolved external symbol _GETCWD@4		DateiSchliessen.obj		

These are mostly linked to some system functions. Does anybody have a possible solution to this issue? Thanks for your help in advance.

 

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
442 Views

Your C++ functions are not STDCALL, and don't have argument conventions that match Fortran defaults with STDCALL. If you'll give us the C++ declaration of INPUT_XML_DATA we may be able to help better,

For INPUT_MC, it is probably sufficient for you to add:

!DEC$ ATTRIBUTES DEFAULT :: INPUT_MC

in the procedure where you call that. You might try adding a similar line for INPUT_XML_DATA to see how that goes.

I am not in favor of using switches such as /iface to change calling conventions - I'd prefer that you use ATTRIBUTES directives in the specific routines to make them STDCALL with the correct names and passing mechanisms.

By the way, USE ISO_C_BINDING. just by itself, accomplishes nothing other than to make some additional declarations available. It doesn't change any behavior.

View solution in original post

0 Kudos
5 Replies
Lorri_M_Intel
Employee
442 Views

When you changed the default to STDCALL, it affected all calls, including those to the portability routines GETCWD and SYSTEM.

To correct the external names for these, please 'USE IFPORT" in any routine that calls either GETCWD or SYSTEM.

                    --Lorri

0 Kudos
Vippis
Beginner
442 Views

Thanks, that solved most of the Linker erros.

But I still have errors when I try to call the functions of the the c++ XML Parser. Do I have to call them differently now?

Severity	Code	Description	Project	File	Line	Suppression State
Error		error LNK2019: unresolved external symbol _INPUT_XML_DATA@48 referenced in function _DATEN_EINLESEN_XML_MOD_mp_DATEN_EINLESEN_XML		Daten_einlesen_XML.obj		
Error		error LNK2019: unresolved external symbol _INPUT_MC@32 referenced in function _DATEN_EINLESEN_XML_MOD_mp_DATEN_EINLESEN_XML		Daten_einlesen_XML.obj		

A short Code snippet

USE, INTRINSIC :: ISO_C_BINDING  ! I used this before already
! This is how I call the function
CALL INPUT_MC(hDocument,datein%Eingabedatei,XML%XMLInputPfad,Ausgabe%MatID_1B,Ausgabe%MatID_2B,AUSGABE%H1,AUSGABE%H2)

 

This how it looks like in c++

extern "C" void INPUT_MC(bool &c_load_okay, char *Dateiname, char *XMLInputPfad, char *MatID_1B, char *MatID_2B, float *H1, float *H2,
    size_t length_Dateiname, size_t length_XMLInputPfad, size_t length_MatID_1B, size_t length_MatID_2B)

 

0 Kudos
mecej4
Honored Contributor III
442 Views

You should probably read the Mixed Languages chapter in the Intel Fortran documentation.

The Fortran compiler, based on your options, has created uppercase names. Perhaps, you could uppercase the external names in the C code.

0 Kudos
Steve_Lionel
Honored Contributor III
443 Views

Your C++ functions are not STDCALL, and don't have argument conventions that match Fortran defaults with STDCALL. If you'll give us the C++ declaration of INPUT_XML_DATA we may be able to help better,

For INPUT_MC, it is probably sufficient for you to add:

!DEC$ ATTRIBUTES DEFAULT :: INPUT_MC

in the procedure where you call that. You might try adding a similar line for INPUT_XML_DATA to see how that goes.

I am not in favor of using switches such as /iface to change calling conventions - I'd prefer that you use ATTRIBUTES directives in the specific routines to make them STDCALL with the correct names and passing mechanisms.

By the way, USE ISO_C_BINDING. just by itself, accomplishes nothing other than to make some additional declarations available. It doesn't change any behavior.

0 Kudos
Vippis
Beginner
442 Views

Hello guys,

Using your hint to use "!DEC$ ATTRIBUTES DEFAULT :: INPUT_MC" solved the issue. Please pardon my clumsy approach. I'm just trying to link these older Fortran programms to python for the first time. I do my best to improve. 

Thanks for your help! :)

0 Kudos
Reply