- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a large, old, mixed-language program that I've been "porting" from the Watcom C and FORTRAN compilers to the MS C and Intel Fortran compilers. In addition, I'm trying to get rid of some stray Windows-specific code that's gotten in over the years, and therein lies my current problem:
At present, the program uses WinMain() as its startup routine, which uses the Windows function GetCommandLine() to build argc and argv, and then calls a function called int "ciexec(int argc, char *argv[])", which had been main() before the program was ported to Windows. However, this causes functions using stdio, e.g. printf(), not to work. So, I tried commenting out the WinMain() stuff and renaming ciexec() back to main(), but then I get this error:
libifcoremt.lib(for_main.obj) : error LNK2019: unresolved external symbol MAIN__
referenced in function main
So, I tried renaming main() to MAIN__(), which allows the program to link, but then I get a run-time error because argc appears to contain a memory address instead of the number of argument and argv is NULL.
I'm completely at a loss about how to:
- get the program to link with the main function named "main()" instead of "MAIN__()", and
- have argc and argv be correct.
Thank you in advance for your help!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My advice is to create a new project as a "console application" and add your code to that. Rewrite the WinMain routine to be a main program unit. Note that making this change also involves linker setting changes so just changing the code is not enough.
Have you considered using the Fortran 2003 intrinsics for getting arguments from the command line?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
MADsblionel:
Fortran is not C. If you want a main program it has to be a PROGRAM or not have a SUBROUTINE, FUNCTION, BLOCK DATA or MODULE first line.
Yes, I'm well aware of that. I don't want a Fortran main program; I want to switch from this:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
int argc;
char **argv;
/* BuildArgVector() uses the Win32 function GetCommandLine() to
populate argc and argv */
BuildArgVector(&argc, &argv);
ciexec(argc, argv);
}
int ciexec(int argc, char **argv) {
/* Fortran gets called inside here */
}
to this:
int main(int argc, char **argv) {
/* Fortran gets called inside here */
}
In other words, I just want it to correctly use the C main function that I already have, without a stupid Win32 wrapper around it!
MADsblionel:
For Fortran programs, the actual "main" entry point is in the run-time library.
Yes, I kinda figured from the "(for_main.obj)" bit in the error message that something related to that was going on. But how do I fix (i.e., get rid of) it?
MADsblionel:
My advice is to create a new project as a "console application" and add your code to that. Rewrite the WinMain routine to be a main program unit. Note that making this change also involves linker setting changes so just changing the code is not enough.
I neglected to mention that I'm compiling from the command-line. I am doing for several reasons:
- When I say "mixed-language," I don't mean just C and Fortran. I mean C, Fortran, and two in-house languages that get precompiled into C and Fortran respectively. That sort of thing doesn't work very well in Visual Studio unless I wrote some kind of extensions, which I have neither the time nor skill to do at the moment.
- There was already an established build system using shell scripts, so I just modified those to call the Intel and MS compilers instead of the Watcom ones.
- I tried to set up a Visual Studio solution (with separate projects per language, as the documentation says), but could never get it to work.
- I don't like the stupid Microsoft GUI-based build system anyway. It's too [censored] hard to figure out what all the [censored] settings are, and it doesn't tell you what it's [censored] doing!
I'll try again to make a Visual Studio project if you want, but I'd really much rather have advice about building from the command line. Speaking of which, here are my current scripts for building C files, building Fortran files, aggregating into a library, and linking:
"C:Program Files (x86)Microsoft Visual Studio 8VCinamd64cl.exe" -Zi -nologo -w -I"c:gtices
ewinc" -DDOS -D_WINDOWS -DNT -c %1 %2 %3 %4 %5 %6 %7 %8 %9
"C:Program Files (x86)IntelCompilerFortran10.1.011em64tinifort" -Zi -nologo -c %1
<
br>for %%a in ( *.obj ) do xilib -nologo -out:"path omylib.lib" "path omylib.lib" %%a
"C:Program Files (x86)Microsoft Visual Studio 8VCinlink.exe" -debug -defaultlib:user32 -defaultlib:advapi32 -out:test.exe *.obj path omylib.lib
I should mention that I'm not some experienced Windows programmer; I'm actually just a student. In fact, I don't even like Windows! I got hired to make this program work in 64-bit mode (porting to Intel/MS compilers is a side-effect of that) because the problem sizes it's being used to solve are getting too big to fit in 4GB of memory. This program has a lot of code, most of which was written before I was born. I haven't even seen the vast majority of it; I'm just dealing with the "Basic System" at the moment, which does things like interpret commands, provide dynamic allocation for old-style Fortran (that may or may not even conform to the '77 standard), etc. The simpler I can make things for myself, the better.
MADsblionel:
Have you considered using the Fortran 2003 intrinsics for getting arguments from the command line?
No, and I would very much prefer not to!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ifort -help gives the basic story.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How are you linking the code? There's a C-calls-Fortran sample provided in version 10 and later under SamplesMixedLanguage. There's a build.bat which builds it from the command line. Compare that to what you're doing and see what the difference is. I think you'll need to specify the link option /subsystem to be console instead of windows.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
MADsblionel:
Oh, I see. Tim's suggestion of -nofor_main is not applicable on Windows - that's for Linux and Mac only.
How are you linking the code? There's a C-calls-Fortran sample provided in version 10 and later under SamplesMixedLanguage. There's a build.bat which builds it from the command line. Compare that to what you're doing and see what the difference is. I think you'll need to specify the link option /subsystem to be console instead of windows.
Modifying my link script to include that as follows:
"C:Program Files (x86)Microsoft Visual Studio
8VCinlink.exe" -debug -subsystem:console -defaultlib:user32 -defaultlib:advapi32
-out:test.exe *.obj path omylib.lib
Makes no difference whatsoever (as I suspected it wouldn't, because the documentation says that setting is the default anyway), and the C=calls-Fortran build script doesn't do anything special.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Okay, so I double-checked that there was no Fortran main, and there wasn't. But at the same time, I did notice this bit of code in a header file: #define main ciexec
Well, guess what: that's why it was telling me that main was undefined when I tried to name it normally, as int main(int argc, char **argv)
, and had to call it MAIN__
instead! And -- I'm guessing here -- by calling it MAIN__
, something thought it was a Fortran routine and screwed up the calling convention for it.
In other words, getting rid of that stupid #define statement fixed my problem. : ) Thanks for your help (since, even though you didn't provide the answer yourself, your suggestion led me to it)!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page