Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

preprocessor directives across libraries

27 views
Skip to first unread message

Christopher Pisz

unread,
Oct 12, 2015, 3:15:03 PM10/12/15
to

I have some code in a library that needs to do one thing if it is being
run "in console mode" and it needs to do another thing if it is being
run as a "windows service"

There is already a preprocessor definition in executables being run in
"console mode" put there by Visual Studio: _CONSOLE

However, I quickly discovered that a #ifdef #else #endif block has
already been substituted when the library is compiled, in which case
_CONSOLE is not defined. It is defined when the executable is compiled,
which occurs after the library.

Surely, this is a common scenario. How do people usually handle it?
While my code is pretty Window's specific, as is the compiler,
preprocessor directives aren't. Is there a common way to handle this?

I really don't want to resort to all user's of the library having to put
their own #ifdef's around every call to my library in order to translate
their define into a variable to be passed as a variable.

Because, people always ask, what are you trying to do? I'll include this
snippet:

// Inside my library
// _CONSOLE is not defined in the library, but is define by the calling
executable
int DoHttpGet()
{
// Open a Winhttp session
// When running in console mode we want to get the user's proxy
information that was set through thier web browser
// Without doing this, the proxy will not get used and http
capturing tools, like Fiddler, will not be able to see our traffic.
//
// When running as a service, we will not be able to get the per
user proxy information without always impersonating a
// user. We don't want to do that. MSDN claims we can set proxy
info it will pick up with the DEFAULT_PROXY_FLAG set using
// netsh on the command line, but that does not seem to work.
#if defined (_CONSOLE)
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);

sessionHandle = WinHttpOpen(L"WinHttpWrapper",
WINHTTP_ACCESS_TYPE_NAMED_PROXY,
proxyConfig.lpszProxy,
proxyConfig.lpszProxyBypass,
0);
#else

sessionHandle = WinHttpOpen(L"WinHttpWrapper",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
#endif

// Snip rest of code
}







--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---

Paavo Helde

unread,
Oct 12, 2015, 4:12:37 PM10/12/15
to
Christopher Pisz <nos...@notanaddress.com> wrote in news:mvh0mc$3jv$1
@dont-email.me:

>
> I have some code in a library that needs to do one thing if it is being
> run "in console mode" and it needs to do another thing if it is being
> run as a "windows service"
>
> There is already a preprocessor definition in executables being run in
> "console mode" put there by Visual Studio: _CONSOLE
>
> However, I quickly discovered that a #ifdef #else #endif block has
> already been substituted when the library is compiled, in which case
> _CONSOLE is not defined. It is defined when the executable is compiled,
> which occurs after the library.

Rightly so. When compiling the library, it is not known in what kind of
application it will be run. If you want it be usable in both modes then
you should find out at run-time which mode it is in, and branch at run-
time, not at compile time with preprocessor. Surely there is a way to do
that. You should also think over what exactly you want to detect, console
mode or service mode (hint: 90+% of Windows applications are neither).

An alternative way would be to define two project configurations, build
two variants of the library and let the client to link to the needed one.
However, this would complicate the building and usage of your library
unnecessarily (if most of the behavior remains the same).

hth
Paavo

Christopher Pisz

unread,
Oct 12, 2015, 7:02:38 PM10/12/15
to
On 10/12/2015 3:12 PM, Paavo Helde wrote:
> Christopher Pisz <nos...@notanaddress.com> wrote in news:mvh0mc$3jv$1
> @dont-email.me:
>
>>
>> I have some code in a library that needs to do one thing if it is being
>> run "in console mode" and it needs to do another thing if it is being
>> run as a "windows service"
>>
>> There is already a preprocessor definition in executables being run in
>> "console mode" put there by Visual Studio: _CONSOLE
>>
>> However, I quickly discovered that a #ifdef #else #endif block has
>> already been substituted when the library is compiled, in which case
>> _CONSOLE is not defined. It is defined when the executable is compiled,
>> which occurs after the library.
>
> Rightly so. When compiling the library, it is not known in what kind of
> application it will be run. If you want it be usable in both modes then
> you should find out at run-time which mode it is in, and branch at run-
> time, not at compile time with preprocessor. Surely there is a way to do
> that. You should also think over what exactly you want to detect, console
> mode or service mode (hint: 90+% of Windows applications are neither).

True, finally found a way to check if running as a service without
having to pass down other defines into libraries, like service name.

Now time to test. Thank you sir.

> An alternative way would be to define two project configurations, build
> two variants of the library and let the client to link to the needed one.
> However, this would complicate the building and usage of your library
> unnecessarily (if most of the behavior remains the same).
>
> hth
> Paavo
>


mark

unread,
Oct 13, 2015, 4:08:42 AM10/13/15
to
On 2015-10-12 21:14, Christopher Pisz wrote:
>
> I have some code in a library that needs to do one thing if it is being
> run "in console mode" and it needs to do another thing if it is being
> run as a "windows service"
>
> There is already a preprocessor definition in executables being run in
> "console mode" put there by Visual Studio: _CONSOLE

"_CONSOLE" has nothing whatsoever to do with what you want to detect.
There are services that run as console subsystem apps as well as
services that run as gui subsystem apps.

Users of your library may well want to switch the subsystem they use,
independent of whether they run as service or not.

> I really don't want to resort to all user's of the library having to put
> their own #ifdef's around every call to my library in order to translate
> their define into a variable to be passed as a variable.

What's wrong with having some library config function that does that
that once?

I don't know what your library is trying to do, but automatically
picking up the proxy with some strange magic without offering an
override capability is generally bad.

0 new messages