CRT Get Module Directory - GetModule Name ??

C

C++8x

Hi, I have a dll written on c. The application loads it dynamically,
using LoadLibrary.
How is it possible to get Dll's own file name (or path) without using
Windows API functions? Is there any functions in CRT that can help me
do that ?
 
K

Keith Thompson

C++8x said:
Hi, I have a dll written on c. The application loads it dynamically,
using LoadLibrary.
How is it possible to get Dll's own file name (or path) without using
Windows API functions? Is there any functions in CRT that can help me
do that ?

There is nothing in standard C that will do what you're trying to do.
The C standard doesn't even mention DLLs. The closest thing to what
you're looking for is probably argv[0], which *usually* points to a
string containing the name of the program.

Try asking in comp.os.ms-windows.programmer.win32.
 
C

C++8x

There is nothing in standard C that will do what you're trying to do.
The C standard doesn't even mention DLLs.  The closest thing to what
you're looking for is probably argv[0], which *usually* points to a
string containing the name of the program.

Thanks for reply!

I will ask the windows group, but I guess the windows way is to call
an Win32 API function. But I don't want to #include <windows.h> for
that. Though, just off the top of my head: I can probably declare
needed API function, and link with one of windows' dll's (kernel32.dll
or user32.dll or whatever) and make sure calling conventions
difference between my c dll and the API function is the same. And name
mangling might be the issue...

But, I don't want to deal with Windows API here.

Well, if there is no way to get the dll's path (and/or .o .so file for
Linux), what can I learn about the dll (.so) using CRT? nothing?

What about main program folder? Can I get the it from the dll without
passing argv[0] to it? Is it stored in an environment variable
accessible for the current process?
 
B

BGB / cr88192

There is nothing in standard C that will do what you're trying to do.
The C standard doesn't even mention DLLs. The closest thing to what
you're looking for is probably argv[0], which *usually* points to a
string containing the name of the program.

<--
Thanks for reply!

I will ask the windows group, but I guess the windows way is to call
an Win32 API function. But I don't want to #include <windows.h> for
that. Though, just off the top of my head: I can probably declare
needed API function, and link with one of windows' dll's (kernel32.dll
or user32.dll or whatever) and make sure calling conventions
difference between my c dll and the API function is the same. And name
mangling might be the issue...

But, I don't want to deal with Windows API here.
-->

use it or don't use it...
ugly hackery like this is ill-advised...

note that some common ways to deal with portability issues are:
put OS-specific code in separate files, and only include them in the build
for a particular OS (downside: this complicates building the project);
make use of the preprocessor ("#ifdef", "#ifndef", "#endif", ...) to mark
off OS-specific sections (nearly all major compilers for major OS's use
special #define's to indicate the OS, CPU arch, compiler, ...);
....

the preprocessor option can be used by itself, or mixed with the
OS-specific-file strategy, to good effect. this can allow essentially
leaving out all the OS-specific stuff when not building for the OS for which
it applies.

admittedly, it is not clean, and hence it is a good idea to partition off
non-portable code into its own areas.

in some cases, I use a name suffix such as 'OS' or 'W32' or 'Lnx' to mark
functions which are inherently non-portable ('OS' mostly for ones where the
internal logic has to be changed for each OS, and 'W32' or 'Lnx' for
functions which are only valid on a particular OS).

if possible, with 'OS' functions, if no good options exist (such as on an
unknown OS) then it may make sense to try to fall back to faking the
facility (if possible), or failing gracefully.

elsewhere, code can then try to be generic and call into these OS-specific
sections with caution.


<--
Well, if there is no way to get the dll's path (and/or .o .so file for
Linux), what can I learn about the dll (.so) using CRT? nothing?
-->

pretty much...
within the bounds of standard C, one can do almost nothing of the sort.

(one may soon find that for nearly much of anything "non-trivial" they will
have to go outside the standard, but this does not necessarily rule out
being able to write portable code).

as an example, consider Quake2:
the code is generally terrible;
it uses things outside the C standard all over the place;
it makes heavy use of OS-specific facilities;
....

yet, it is still relatively easy to port:
it builds on Linux, and it builds on Windows, and it builds on OSX;
it can be built fairly easily with Cygwin, with MinGW, or with MSVC;
people have gone as far as to get it to build on .NET and Mono (but I guess
this was more of a "port" though);
....

and, it does all this without resorting to any of the usual "portability
tools" (there is no "configure" in the mix, ...).


this is in contrast to many claimed "cross platform" apps, which are very
difficult to get to build outside of the narrow OS(s) they are designed to
work with (like an app which claims to be cross-platform, but uses
"configure", tightly depends on GTK, ... and hence is very difficult to
build on Windows, so help you if you want to use MSVC...).

IMO, "configure" is a false sense of security, as many using it I guess
expecting it to "magically" make their code portable.


<--
What about main program folder? Can I get the it from the dll without
passing argv[0] to it? Is it stored in an environment variable
accessible for the current process?
-->

once again, there is no way to do this in the C standard, but the problem is
much easier with the process described earlier.

so, maybe rather than thinking of it as "all or nothing", instead consider
it more like this:
stategy A on Windows;
strategy B on Linux;
stategy C on ...;
fail gracefully if unknown (such as returning NULL for the image name, ...),
and have the caller willing to accept NULL as a valid answer.


or such...
 
K

Keith Thompson

C++8x said:
There is nothing in standard C that will do what you're trying to do.
The C standard doesn't even mention DLLs.  The closest thing to what
you're looking for is probably argv[0], which *usually* points to a
string containing the name of the program.

Thanks for reply!

I will ask the windows group, but I guess the windows way is to call
an Win32 API function. But I don't want to #include <windows.h> for
that.

Why not?

You're doing something very Windows-specific. Surely the Win32 API is
exactly what you should be using.
Though, just off the top of my head: I can probably declare
needed API function, and link with one of windows' dll's (kernel32.dll
or user32.dll or whatever) and make sure calling conventions
difference between my c dll and the API function is the same. And name
mangling might be the issue...

Yes, you can reinvent the wheel if you really want to. The resulting
code will be just as Win32-specific as if you had used the proper
interfaces, but less stable.
But, I don't want to deal with Windows API here.

I don't see that you have a choice, but I'm not a Windows expert.
Well, if there is no way to get the dll's path (and/or .o .so file for
Linux), what can I learn about the dll (.so) using CRT? nothing?

CRT means C Runtime, right?

Your implementation undoubtedly provides a C runtime library that
implements both the standard C library, as specified in in the C
standard, and some additional functionality. If there's anything in
there that does what you want, it's in the implementation-specific
portion, and you'll need to ask in an implementation-specific forum.
I already suggested comp.os.ms-windows.programmer.win32.
What about main program folder? Can I get the it from the dll without
passing argv[0] to it? Is it stored in an environment variable
accessible for the current process?

Here's what the C standard says about the strings to which the elements
of the argv array point:

If the value of argc is greater than zero, the string pointed to
by argv[0] represents the program name; argv[0][0] shall be the
null character if the program name is not available from the host
environment. If the value of argc is greater than one, the strings
pointed to by argv[1] through argv[argc-1] represent the program
parameters.

So argv[0] may or may not point to a string representing the program
name. If it does, you may or may not be able to get a directory or
folder name from it.

The standard says nothing about any specific environment variables; it
just provides the getenv() function to query the values of environment
variables if you already know their names. (On the systems I'm
familiar with, the information you're looking for isn't available in
an environment variable.)
 
C

C++8x

....

Thanks BGB. Writing portable code is not that trivial, indeed, But it
wasn't my goal here.
 
C

C++8x

CRT means C Runtime, right?
Right.

I guess, when I have C code in a dll (.so), from the code's standpoint
it is just part of a main program, and not separate module (dll,
or .so file)


Thanks Keith!
 

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,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top