Name mismatch when using Fortran shared library - c

I managed to successfully compile a shared library using IFORT that contains some .obj files (i.e. dependencies) compiled by Visual Studio C.
When trying to use this shared library in a Fortran program it fails saying Example.obj : error LNK2019: unresolved external symbol TEST_mp_EXECUTE referenced in function MAIN__.
When I use the tool dumpbin.exe I can see that function execute is in the shared library. Any idea why this mismatch of names that is making the compilation of the Fortran program to fail?
Content of file Test.c:
__declspec(dllexport) int execute(void);
int execute(void)
{
return 2 + 3;
}
File Test.c successfully compiled with Microsoft Visual Studio C as follows (the result is an object file named Test.obj):
cl.exe Test.c /FoTest.obj
Content of file Test.f90:
MODULE Test
USE, INTRINSIC :: iso_c_binding, ONLY: c_int
IMPLICIT NONE
INTERFACE
INTEGER(c_int) FUNCTION execute() BIND(C, name = "execute")
USE, INTRINSIC :: iso_c_binding, ONLY: c_int
END FUNCTION
END INTERFACE
END MODULE
File Test.f90 successfully compiled with IFORT as follows (the result is a shared library named Test_dll.dll along with its header file named Test_dll.lib, and a Fortran module file named test.mod):
ifort.exe Test.obj /Qm64 /LD /FeTest_dll.dll
Content of file Example.f90:
PROGRAM Example
USE test
state = execute()
END PROGRAM
Now, when trying to compile file Example.f90 as ifort.exe Example.f90 Test_dll.lib it fails saying Example.obj : error LNK2019: unresolved external symbol TEST_mp_EXECUTE referenced in function MAIN__. Any idea what is going on?

Note that you have two sources that compile to a test.obj - the Fortran and the C. Also, the cl command you showed tries to generate an executable. Here's how to do it right:
cl /c /MD /Foctest.obj test.c
ifort /dll test.f90 ctest.obj
ifort example.f90 test.lib
I added /MD to the C compile to get a compatible set of run-time libraries. This generated the executable without errors.

Related

Problem compiling C/Fortran code together with pgi on windows: "main already defined"

Below is a toy example of the C/Fortran files I want to compile together.
The C file
void testfunc();
int main(void)
{
testfunc();
}
The Fortran file
subroutine testfunc() bind (C, name = "testfunc")
write(*,*) "Hello World!"
end subroutine
Using gcc, I can generate a binary with the command
gfortran -o my_prog main.c testfunc.f90
However, when I try the same with pgf90
pgf90 -o my_prog main.c testfunc.f90
I get the following error message:
main.obj : error LNK2005: main already defined in f90main.obj
f90main.obj : error LNK2019: unresolved external symbol MAIN_ referenced in function main
Is there a standard procedure for compiling C+Fortran with pgi on Windows?
Add the flag "-Mnomain" to the link to have the compiler not include the F90 main object to the link and instead use the user supplied C main.

Link DLL in Borland C++ compiler

I use freecommandlinetools compiler bcc32. I need to use third party dll in my program. I'd prefer not to call LoadLibrary and GetProcAddress, but rather to link the dll in my program to call the dll functions directly.
#include "somelibrary.h"
int main() {
somefunction(); // defined in somelibrary.dll
}
I see unresolved externals in attempt to compile. How to convince the linker to link with the somelibrary.dll?
You must create a .lib in order to link the dll directly.
Supposing your dll is user32.dll :
implib -a -c -f user32.lib user32.dll
Will create user32.lib with all the symbols of user32.dll. Then link your project with user32.lib instead of user32.dll.
You can use the impdef.exe command to see the symbols exported by the dll. If these symbols already start with an underscore '_', you can omit the -a in the implib command.

Clang, Microsoft linker and standard library

I have successfully built Clang with Microsoft C++ and I'm trying to get it to compile a hello world test case; it gets as far as generating an object file, linking with the standard library being the remaining stumbling block:
hello-202520.o : error LNK2019: unresolved external symbol _printf referenced in function _main
LINK : error LNK2001: unresolved external symbol _mainCRTStartup
There are comments from previous years saying Clang doesn't yet do Windows linking at all, but I get the impression those are outdated, and indeed it does now seem to be able to generate Windows format object files:
clang -c hello.c
ren hello.o hello.obj
link hello.obj
... doesn't barf, so the file format seems to be correct, but still gets the unresolved external symbol errors. Likely guess is the Microsoft compiler tags its output object files with an indication of the standard library they need to be linked with whereas Clang doesn't, and eyeballing a hex dump of the respective object files seems to confirm this and gives a hint of the linker command line to use:
link /defaultlib:libcmt /defaultlib:oldnames hello.obj
I had high hopes by this stage but alas it still gives the same unresolved external symbol errors.
What am I still missing?
Turns out Clang was by default generating 32-bit code but I was using 64-bit MSC, and the leading _ on C symbols has been dropped with the move to x64, so specifying -m64 on the clang command line did the job.

Visual Studio C++ link with psapi.lib

I have written a C Program which calls the function, GetModuleInformation() which is defined in psapi.h
I am using Microsoft Visual Studio C++ command line compiler (cl.exe) for compiling and linking the program.
I have included the psapi.h header file:
#include <psapi.h>
when I try to compile using:
cl program.c
It generates the object file, however fails during the linking stage with the error:
program.obj : error LNK2019: unresolved external symbol _GetModuleInformation#16 ref
erenced in function _main
program.exe : fatal error LNK1120: 1 unresolved externalsprogram.obj : error LNK2019: unresolved external symbol _GetModuleInformation#16 ref
I also place the psapi.lib file in the same folder where the source code file (program.c) is placed, however even then I get the same error message as above.
How do I successfully link it using the command line compiler (cl.exe)?
Method 1
If you want to compile from the command line with cl.exe you can use the /link option to specify linker options :
cl /TC program.c /link psapi.lib
Method 2
The following pragma directive causes the linker to search in your source file for the psapi.lib library while linking .
#pragma comment( lib, "psapi.lib" )
Possible reason for your errors can be, if psapi.lib is missing in a list of additional libraries of linker.
To resolve this, use the following /LIBPATH option :
cl /TC program.c /link Psapi.Lib /LIBPATH:C:\MyLibFolder\
Where C:\MyLibFolder specifies a path to the folder, that contains your psapi.lib .
Also, you can try to set the proper /SUBSYSTEM option .
For a Console application use :
/SUBSYSTEM:CONSOLE
Solution to similar problem here .
Example on using the GetModuleInformation function :
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#pragma comment( lib, "psapi.lib" )
int main(void)
{
MODULEINFO minfo = {0};
GetModuleInformation( GetCurrentProcess(), GetModuleHandle( "psapi.dll" ), &minfo, sizeof(minfo) );
/* printf("%X", minfo.lpBaseOfDll); /* The load address of the module */
return 0;
}
The code has been tested on Windows 7 and XP .
The output from linking session is :
program.c
/out:program.exe
psapi.lib
/LIBPATH:C:\MyLibFolder\
/SUBSYSTEM:CONSOLE
/VERBOSE
program.obj
Starting pass 1
Processed /DEFAULTLIB:uuid.lib
Processed /DEFAULTLIB:LIBCMT
Processed /DEFAULTLIB:OLDNAMES
Searching libraries
Searching C:\MyLibFolder\psapi.lib:
Found _GetModuleInformation#16
Referenced in program.obj
Loaded psapi.lib(PSAPI.DLL)
Found __IMPORT_DESCRIPTOR_PSAPI
Referenced in psapi.lib(PSAPI.DLL)
Loaded psapi.lib(PSAPI.DLL)
Found __NULL_IMPORT_DESCRIPTOR
Referenced in psapi.lib(PSAPI.DLL)
Loaded psapi.lib(PSAPI.DLL)
...
If vsvars32.bat and all appropriate environment variables in your Visual Studio are set correctly the above linker options will produce a valid executable(.exe) file.

Linking errors in windows

I'm trying to compile a c-file, cfile.c, which calls a subroutine in a fortran file, fortfile.f, and it's necessary for me to compile it on windows. The commands I'm using to do so are, in order:
icl /c /Qipo cfile.c
ifort /c /Qipo fortfile.f
icl cfile.obj fortfile.obj /Qipo
I use icl for linking because ifort seems to require the option nofor_main which is not available in windows. But when I do these commands, I get the following error:
ipo: error #11023: Not all components required for linking are present on command line
ipo_5220.obj: error LNK2019: unresolved external symbol _pythagoras_ referenced in function _main
Note that pythagoras is the subroutine called in fortran. Any ideas what's the matter?

Resources