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.
Related
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.
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.
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.
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?
I am trying to compile a C program using the Intel icl compiler under MINGW/64. The program uses the following code:
#include <Userenv.h>
HANDLE process;
HANLDE token;
GetUserProfileDirectory(process, TOKEN_QUERY, &ptoken)
I am using the following compile command:
$ icl -g -DMINGW32 -DTESTMAIN user.c -o user -UserEnv.Lib
and I am linking against the UserEnv.Lib from the Microsoft SDK.
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version Microsoft (R) Incremental Linker Version 9.00.21022.08
-out:user.exe
user.obj
user.obj : error LNK2019: unresolved external symbol __imp_GetUserProfileDirectoryA referenced in function main
Any idea how to solve this problem?
SOLUTION:
The solution is to use
/link /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Lib/x64/UserEnv.Lib /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Lib/x64/A
I copied the file UserEnv.lib from the Microsoft SDK (x64, 6.0) into the current working directory and compiled the program with
$ icl test.c -DMINGW32 ./UserEnv.Lib
LNK2019: unresolved external symbol __imp_GetUserNameA referenced in function main test.obj : error LNK2019: unresolved external symbol __imp_OpenProcessToken referenced in function main test.obj : error LNK2019: unresolved external symbol –
and I am still getting the unresolved symbols.
Olaf
You need to add userenv.lib to your input libraries for the linker to see GetUserProfileDirectory().
EDIT: It's been a while since I've touched an Intel compiler, but IIRC you're supposed to use /link to introduce linker options:
$ icl test.c -DMINGW32 /link ./UserEnv.Lib