linker error

A

Alf P. Steinbach

* James Kanze:
James said:
[..]
I know this is off topic, but the issue comes up so often: what
the hell is a "console application"? How does it differ from
any other application, other than, perhaps, it doesn't use
certain libraries? (In which case, of course, you don't need to
click anything. Just don't include the appropriate headers, nor
link against the corresponding library.)
It's specific to Windows OS, and how the hosting environment tries
to provide (or exclude) certain features we're so used to in some
other environs.

To the OS, or to the development environment? If I look at my
Windows system, I don't see any difference between applications;
they're all .exe files, regardless of what they do. As far as I
can tell, all of the facilities of the OS are there for all
programs to use, if they want.

Not quite. The difference between services provided for GUI versus
console subsystem isn't that great: just that a console program gets a
console window by default. Other subsystems are drivers, and earlier
Windows supported OS/2 and Posix 0.9 console subsystems, the latter
providing a Posix compatibility box. The Posix compatibility subsystem
is now replaced with a distinct *nix environment called Windows Services
For Unix, SFU, which ironically bundles the g++ compiler...

I'm not sure what you mean by a "normal" Windows app.
Something that isn't a console app? I just started Netscape
from a "command prompt" window (the Windows equivalent of a
terminal window, I think), and it started exactly like it does
when I click on the icon. No output appears in the terminal
window, of course, for the simple reason that netscape doesn't
output to standard out.

You're right. If you start a GUI app that produces stdout output,
whether that output appears in a console depends on whether stdout is
hooked up to the console window. The old Windows command interpreter
doesn't hook up stdout for a GUI app by default, but you can pipe it
through cat or more or findstr or whatever, or redirect it to a file.

"/dev/null". Again, that's not a characteristic of the program,
but of the way it is invoked.

Right, 100%.


[snip]
Now that can't be true. I often write little test programs in
Windows, to see what happens with VC++, and I've never created a
console in any of them. I just compile them and run them.
Almost exactly as I do under Unix (and the sources are
identical, since it is the same remote mounted file).

Right, but I suspect it is because you didn't know that you produced
console programs. If you build the same source as a GUI app, you'll
need to either use some other command interpreter than Windows' old one,
or else redirect stdin and stdout explicitly.

And that, really, is more or less what I was asking: are these
programs "console applications", or something else?

Probably, yes.

Depends on how you build them.


[snip]
But it still has a .exe suffix, and can be invoked from the
command line. (Or is Netscape not a Windows application? I'm
getting more and more confused.)

A Windows application isn't a DLL, but has the same executable format as
a DLL (Portable Executable, PE).

Do read the PDF I linked to, <url:
http://home.no.net/dubjai/win32apitut/01.pdf>.

Follow-ups set to [comp.os.ms-windows.programmer.win32].
 
J

Jerry Coffin

[ ... ]
To the OS, or to the development environment? If I look at my
Windows system, I don't see any difference between applications;
they're all .exe files, regardless of what they do. As far as I
can tell, all of the facilities of the OS are there for all
programs to use, if they want.

They all show up as .exe files. The 'optional header' in a PE file
(which isn't really optional for a PE file) contains a field that
specifies the subsystem for which that executable was compiled.

For Win32 programs this makes _very_ little difference: it mostly just
governs how the program is started up (i.e. whether it gets a console by
default or not). Though I believe they've been removed now, Windows NT
originally supported POSIX and OS/2 subsystems as well -- and those did
NOT have access to Win32 functions.

[ ... ]
Now that can't be true. I often write little test programs in
Windows, to see what happens with VC++, and I've never created a
console in any of them. I just compile them and run them.
Almost exactly as I do under Unix (and the sources are
identical, since it is the same remote mounted file).

Most Windows linkers set the console subsystem field based on what they
find as an entry point for your program -- if it contains a function
named "WinMain", they set it to use the Windows subsystem. If it
contains a function named "main", they set it to use the console
subsystem (they also recognize a few variants like 'wmain'...)

That means portable code that uses 'main' will become a console
subsystem program unless you specify otherwise.
And that, really, is more or less what I was asking: are these
programs "console applications", or something else? And would
my real applications be "console applications" if I compiled and
ran them under Windows, or something else, even if they are
normally started automatically by the system at a certain time
each day, and they're standard output is to a black hole?

See above -- if they start as portable code, they'll produce console
applications by default. That gives them a stdin, stdout and stderr, but
what they're connected to depends entirely on how they're invoked -- if
you start them from a normal command line you can leave them connected
to the screen/keyboard or you can redirect them about the same way you
would under a typical shell.

If they're started by something like cron, they'll typically be started
as a "detached" process -- the streams all exist, but output goes to a
black hole, and input always yields EOF.

[ ... ]
But it still has a .exe suffix, and can be invoked from the
command line. (Or is Netscape not a Windows application? I'm
getting more and more confused.)

It looks to me like he's just trying to be confusing here. Executables
and DLLs use identical file formats (PE files in both cases).
Effectively, however, there are significant differences -- the OS knows
to create a new process when you try to load an executable, whereas a
DLL is normally loaded into some existing process.

[ ... ]
I've vaguely heard about "WinMain", but from what little I
understand, it's basically just part of an application
framework. It's a function, rather than a class, because the
application framework is designed to support a C API, but it's
basically the same thing; the application framework contains
main somewhere, sets itself up, and then calls this other
function. But of course, you don't have to use this framework,
and you'd only use it if its services corresponded to what you
need.

WinMain has nothing to do with any framework beyond Windows itself. If
your program contains a WinMain, it normally will NOT contain any
function named 'main' anywhere. Whether you write a main or a WinMain,
your program will, however, contain some other function as it's actual
entry point from the OS -- Windows doesn't do anything like collecting
comand line arguments to supply to the program. Its entry point gets the
command line, parses it, and then passes the results to main or WinMain.

There's a different entry point for each, because they expect different
arguments, but either it's there -- supplied in the runtime library.

[ ... ]
What subsystems? And what does this have to do with "console
application"? Every modern OS has a number of subsystems; I'd
say that the split was stricter (and the sophistication higher)
under Unix. (At least, every time I use Windows, I get the
impression of going back 10 or 15 years in time.)

Unix (per se) doesn't have subsystems in the Windows sense. Windows NT
was originally conceived as (at least sort of) a microkernel. It has a
native API that most people never use. Originally, it had (on top of
that) subsystems for Win32, Win32, POSIX and OS/2.

Nowadays, they've removed the POSIX and OS/2 subsystems, so Win32 is all
that's left. Both windowed and console applications run under the Win32
subsystem. For a _few_ purposes, they're (sort of) treated as separate
subsystems, but for most purposes, it's just the Win32 subsystem either
way.

As far as sophistication goes, I suspect it's a much a matter of
viewpoint as anything else -- when I run Unix (or Linux, BSD, etc.) I
get the feeling of having just stepped back 10 or 15 years as well...

[ ... ]
That's my impression, and that's the way similar tools work
under Unix. In general, the OS only has one basic way to start
a program, which can be mapped more or less directly to a
command line.

This _is_ somewhat different: Windows only provides on way to start a
program, but it does NOT map to much of anything. The real entry point
for a program always has the signature 'unsigned int entryPoint(void)'.
It's (always) up to some code in the program itself to do things like
retrieving and parsing its command line, if it chooses to do so at all.

I believe this is largely because Windows was originally designed around
the idea of using wide character strings throughout, but they realized
that most existing code was designed around the interface to the system
being narrow character strings.

Rather than attempt to decree how this gap should be bridged, they left
it to the program to decide what to do. OTOH, they provided enough to
make it pretty easy to build that bridge (e.g. a function to take a
command line a split it into arguments) but also give enough flexibility
that (for example) it's fairly trivial to receive command line arguments
as UTF-16, UTF-8, UTF-7, etc.
 
J

James Kanze

* James Kanze:
* Victor Bazarov:
[...]
I know this is off topic, but the issue comes up so often: what
the hell is a "console application"?
See <url:http://home.no.net/dubjai/win32apitut/01.pdf>, written by
yours truly (ahem).

This is the third time I'm trying to answer---Google doesn't
seem to want me to thank you:). But the article is excellent.
In sum, Windows associates some extra attributes with a .exe
file, which you can set when linking. One of these attributes
(called subsystem, which seems like a funny name for it) is used
by the various system utilities which start processes to control
how they manage the process. A "console application" is an
executable with this attribute set to console.
[snip]
Unless I've misunderstood something greatly, in the end, an
application is an application. If it invokes some system
function which opens a window, and plays around in it, then it
is a GUI (or Windowing) application, but that's a result of the
code the programmer wrote, and nothing else. The applications I
write don't normally do this: are they automatically console
applications (even if they are started by a cronjob, or at
system start-up, with cin, cout and cerr connected to
"/dev/null")?
No, the difference is the specification of subsystem in the executable,
which gets different services from Windows depending on the subsystem.
The problem is that Microsoft's C++ tools treat those subsystems
differently by default, in order to cater to limitations of late 1980's
16-bit Windows. It's extremely silly.

It's definitly a different approach to what I'm used to. For
example, the shells I use (including under Windows) normally
wait for a program to finish (regardless of this attribute under
Windows); if I don't want the shell to wait, I tell it myself
(by appending a '&' character to the end of the command). If I
want it to start in a terminal window, I use something like
"xterm ... -e program" to start it, rather than just "program".
And so on; as user, I choose what I want, rather than having the
program author decide for me.
 
J

James Kanze

[ ... ]
To the OS, or to the development environment? If I look at my
Windows system, I don't see any difference between applications;
they're all .exe files, regardless of what they do. As far as I
can tell, all of the facilities of the OS are there for all
programs to use, if they want.
They all show up as .exe files. The 'optional header' in a PE file
(which isn't really optional for a PE file) contains a field that
specifies the subsystem for which that executable was compiled.

What's a PE file? And what do you mean by "optional header"?
I'm sure that .exe file have a specific format, just as a.out
files do under Unix; do you mean a header section in this
format?
For Win32 programs this makes _very_ little difference: it mostly just
governs how the program is started up (i.e. whether it gets a console by
default or not). Though I believe they've been removed now, Windows NT
originally supported POSIX and OS/2 subsystems as well -- and those did
NOT have access to Win32 functions.

I got that from Alf's paper; it's an attribute which is
associated with a .exe. (Presumable, there is a system API with
which I can read the attribute, so if I wanted to start a
program from one of my programs, I could also test and handle it
differently.)
[ ... ]
Now that can't be true. I often write little test programs in
Windows, to see what happens with VC++, and I've never created a
console in any of them. I just compile them and run them.
Almost exactly as I do under Unix (and the sources are
identical, since it is the same remote mounted file).
Most Windows linkers set the console subsystem field based on what they
find as an entry point for your program -- if it contains a function
named "WinMain", they set it to use the Windows subsystem. If it
contains a function named "main", they set it to use the console
subsystem (they also recognize a few variants like 'wmain'...)
That means portable code that uses 'main' will become a console
subsystem program unless you specify otherwise.

But I can specify otherwise. Why not?

BTW: I wouldn't have understood what was meant by "subsystem"
here, either, if I hadn't read Alf's paper. From what I
understand, it's really just an attribute associated with the
..exe file (something in a special secion of the .exe, perhaps);
it's not really what one would understand by "subsystem"
normally. (If I understood Alf's paper correctly, Microsoft
linkers do also link in an additional library if they decide
that my program is a "windows" application, but that is, again,
still another issue.)
See above -- if they start as portable code, they'll produce console
applications by default. That gives them a stdin, stdout and stderr, but
what they're connected to depends entirely on how they're invoked -- if
you start them from a normal command line you can leave them connected
to the screen/keyboard or you can redirect them about the same way you
would under a typical shell.
If they're started by something like cron, they'll typically be started
as a "detached" process -- the streams all exist, but output goes to a
black hole, and input always yields EOF.

Just like Unix. (In Unix, "/dev/null" is the name of a device
which simply throws away anything output to it, and returns EOF
if you attempt to read it.)
[ ... ]
But it still has a .exe suffix, and can be invoked from the
command line. (Or is Netscape not a Windows application? I'm
getting more and more confused.)
It looks to me like he's just trying to be confusing here. Executables
and DLLs use identical file formats (PE files in both cases).
Effectively, however, there are significant differences -- the OS knows
to create a new process when you try to load an executable, whereas a
DLL is normally loaded into some existing process.

That's what I'd always thought. (On the other hand, there are
significant differences between the way Windows handles .dll's,
and Unix handles .so's. My impression, in fact, is that they
are much like the differences between how the systems handle the
way you start a program. Under Windows, the decisions are
handled upstream, by the person who provides the program/DLL;
under Unix, they're made by the user, when he uses it.)
[ ... ]
What subsystems? And what does this have to do with "console
application"? Every modern OS has a number of subsystems; I'd
say that the split was stricter (and the sophistication higher)
under Unix. (At least, every time I use Windows, I get the
impression of going back 10 or 15 years in time.)
Unix (per se) doesn't have subsystems in the Windows sense. Windows NT
was originally conceived as (at least sort of) a microkernel. It has a
native API that most people never use. Originally, it had (on top of
that) subsystems for Win32, Win32, POSIX and OS/2.

OK. Now I see where the name comes from, as well.
Nowadays, they've removed the POSIX and OS/2 subsystems, so Win32 is all
that's left. Both windowed and console applications run under the Win32
subsystem. For a _few_ purposes, they're (sort of) treated as separate
subsystems, but for most purposes, it's just the Win32 subsystem either
way.

Which is doubtlessly why the use of the name subsystem seems so
strange to me in this case. Still another historical anomaly.
As far as sophistication goes, I suspect it's a much a matter of
viewpoint as anything else -- when I run Unix (or Linux, BSD, etc.) I
get the feeling of having just stepped back 10 or 15 years as well...

With regards to what? I don't have the applications that I have
under Windows, or they don't look as sleek, but at the system
level, I've got a lot more functionality: multiple desktops,
windows on many different machines, etc.
[ ... ]
That's my impression, and that's the way similar tools work
under Unix. In general, the OS only has one basic way to start
a program, which can be mapped more or less directly to a
command line.
This _is_ somewhat different: Windows only provides on way to start a
program, but it does NOT map to much of anything. The real entry point
for a program always has the signature 'unsigned int entryPoint(void)'.
It's (always) up to some code in the program itself to do things like
retrieving and parsing its command line, if it chooses to do so at all.

All of which is transparent to the C++ programmer, of course:).

If I'd have thought about it, I would have realized that this
was probably the case; that's the way it worked on every system
I've seen except Unix. But the concept of a "command line" is
still there; if program A starts program B, it still can provide
the equivalent of a command line somewhere. If I associate a
program with a file type, I specify a "command line" which is
used to invoke the program. There is some sort of mapping
between command line and what the program can see and use.
 
J

Jerry Coffin

On Jul 25, 6:47 pm, Jerry Coffin <[email protected]> wrote:

[ ... ]
What's a PE file? And what do you mean by "optional header"?
I'm sure that .exe file have a specific format, just as a.out
files do under Unix; do you mean a header section in this
format?

Sorry -- PE is "Portable Executable" format, which is a variation on
COFF, and yes, it's the current format for Windows executables. COFF
defines a couple of fields for what it calls an optional header -- but
to be a PE file, that optional header has to be included in a specific
format.

[ ... ]
But I can specify otherwise. Why not?

I'm not sure I follow. Why not what? If you mean, why wouldn't you do
that, the main reason would be that you plan to use the console streams,
so you want them set up by default, which will happen if it's marked for
the console subsystem, but not if it's marked for the windows subsystem
(at least the startup code supplied by the compilers I've looked at
didn't do include that by default...)

[ ... ]
That's what I'd always thought. (On the other hand, there are
significant differences between the way Windows handles .dll's,
and Unix handles .so's. My impression, in fact, is that they
are much like the differences between how the systems handle the
way you start a program. Under Windows, the decisions are
handled upstream, by the person who provides the program/DLL;
under Unix, they're made by the user, when he uses it.)

I'm not sure I understand exactly what differences you're talking about
here...

[ ... ]
With regards to what? I don't have the applications that I have
under Windows, or they don't look as sleek, but at the system
level, I've got a lot more functionality: multiple desktops,
windows on many different machines, etc.

Well, to continue one of your examples, Windows does support multiple
desktops -- but I haven't been able to find X/Unix functionality similar
to the multiple window stations supported by Windows. Under Windows,
each desktop lives in a window station. Most "global" objects like the
clipboard are only really shared among the desktops in a window station.
Under X, the clipboard is managed by a process of its own, but I haven't
seen a capability to designate (for example) that these three desktops
share one clipboard, while those two share a different one.

[ ... ]
All of which is transparent to the C++ programmer, of course:).

Yes -- unless he chooses to get involved, of course.
 
J

James Kanze

[ ... ]
But I can specify otherwise. Why not?
I'm not sure I follow. Why not what?

Just "why not?" Why not do it like Microsoft does? It's no
worse (nor any better) than some other solutions.
[ ... ]
That's what I'd always thought. (On the other hand, there are
significant differences between the way Windows handles .dll's,
and Unix handles .so's. My impression, in fact, is that they
are much like the differences between how the systems handle the
way you start a program. Under Windows, the decisions are
handled upstream, by the person who provides the program/DLL;
under Unix, they're made by the user, when he uses it.)
I'm not sure I understand exactly what differences you're talking about
here...

The fact that with Windows DLL's, you specify which symbols are
exported in the source file, using language extension (or in a
second file, which will be read by the linker), where as with
Unix, you specify whether other so's can see the symbols in your
so by means of an option to dlopen, when you load the object.
Under Windows, the author of the dynamically linked object
chooses what will and what will not be visible; under Unix, the
user chooses when loading the object. (But that's a radical
simplification, of course.)
[ ... ]
With regards to what? I don't have the applications that I have
under Windows, or they don't look as sleek, but at the system
level, I've got a lot more functionality: multiple desktops,
windows on many different machines, etc.
Well, to continue one of your examples, Windows does support multiple
desktops -- but I haven't been able to find X/Unix functionality similar
to the multiple window stations supported by Windows. Under Windows,
each desktop lives in a window station. Most "global" objects like the
clipboard are only really shared among the desktops in a window station.
Under X, the clipboard is managed by a process of its own, but I haven't
seen a capability to designate (for example) that these three desktops
share one clipboard, while those two share a different one.

I'm not sure what the difference is under Windows, but it sounds
like you've basically got two different terminals under X. (A
terminal under X can have more than one screen.)
[ ... ]
All of which is transparent to the C++ programmer, of course:).
Yes -- unless he chooses to get involved, of course.

Agreed. (IMHO: Not having access to the actual command line
is a flaw in the Unix design. There are cases where you want to
differ e.g. filename expansion; under MS-DOS, I had a library
which broke up the command line something like the way Unix
does, including expansion of things like *.c. And one of my
"standard" options was -R, which means recurse on the current
directory, expanding the filenames in all of its subdirectories
as well. And a -o option which would accept such names as well,
mapping each input filename to a corresponding output filename.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,201
Latest member
KourtneyBe

Latest Threads

Top