Windows library file path

Навигация по файловой системе File System Navigation

Заголовок реализует техническую спецификацию файловой системы C++ ISO/IEC TS 18822:2015 (окончательный вариант черновика: ISO/IEC JTC 1/SC 22/WG 21 N4100) и имеет типы и функции, позволяющие создавать независимый от платформы код для навигации по файловой системе. The header implements the C++ File System Technical Specification ISO/IEC TS 18822:2015 (Final draft: ISO/IEC JTC 1/SC 22/WG 21 N4100) and has types and functions that enable you to write platform-independent code for navigating the file system. Поскольку это межплатформенное приложение, оно содержит интерфейсы API, не относящиеся к системам Windows. Because it’s cross-platform, it contains APIs that aren’t relevant for Windows systems. Например, is_fifo(const path&) всегда возвращает значение false в Windows. For example, is_fifo(const path&) always returns false on Windows.

Обзор Overview

Используйте API для следующих задач: Use the APIs for the following tasks:

выполнение итерации по файлам и каталогам в указанном пути; iterate over files and directories under a specified path

получение сведений о файлах, включая время создания, размер, расширение и корневой каталог; get information about files including the time created, size, extension, and root directory

составление, разделение и сравнение путей; compose, decompose, and compare paths

Создание, копирование и удаление каталогов create, copy, and delete directories

копирование и удаление файлов. copy and delete files

Дополнительные сведения о вводе-выводе файлов с помощью стандартной библиотеки см. в разделе Программирование iostream. For more information about File IO using the Standard Library, see iostream Programming.

Пути Paths

Создание и составление путей Constructing and composing paths

Пути в Windows (начиная с XP) изначально хранятся в Юникоде. Paths in Windows (since XP) are stored natively in Unicode. path Класс автоматически выполняет все необходимые преобразования строк. The path class automatically does all necessary string conversions. Он принимает аргументы как для широких, так и для узких символьных массивов, а также для std::string std::wstring типов, отформатированных как UTF8 или UTF16. It accepts arguments of both wide and narrow character arrays, and both std::string and std::wstring types formatted as UTF8 or UTF16. Класс path также автоматически нормализует разделители путей. The path class also automatically normalizes path separators. В аргументах конструктора в качестве разделителя каталогов можно использовать одиночную косую черту. You can use a single forward slash as a directory separator in constructor arguments. Этот разделитель позволяет использовать одни и те же строки для хранения путей в средах Windows и UNIX: This separator lets you use the same strings to store paths in both Windows and UNIX environments:

Для объединения двух путей можно использовать перегруженные операторы / и /= , которые аналогичны операторам + и += в std::string и std::wstring . To concatenate two paths, you can use the overloaded / and /= operators, which are analogous to the + and += operators on std::string and std::wstring . path Объект будет удобным образом предоставлять разделители, если это не так. The path object will conveniently supply the separators if you don’t.

Проверка путей Examining paths

Класс Path имеет несколько методов, возвращающих сведения о различных частях пути. The path class has several methods that return information about various parts of the path itself. Эта информация отличается от сведений о сущности файловой системы, на которую может ссылаться. This information is distinct from the information about the file system entity it might refer to. Можно получить корень, относительный путь, имя файла, расширение файла и другие сведения. You can get the root, the relative path, the file name, the file extension, and more. Можно выполнять итерацию по объекту path для проверки всех папок в иерархии. You can iterate over a path object to examine all the folders in the hierarchy. В следующем примере показано, как выполнить итерацию по объекту пути. The following example shows how to iterate over a path object. И, как получить сведения о его частях. And, how to retrieve information about its parts.

Читайте также:  Не могу установить драйвер amd radeon windows 10

Код создает следующие выходные данные: The code produces this output:

Сравнение путей Comparing paths

Класс path перегружает операторы сравнения на равенство как std::string и std::wstring . The path class overloads the same comparison operators as std::string and std::wstring . При сравнении двух путей необходимо выполнить сравнение строк после нормализации разделителей. When you compare two paths, you make a string comparison after the separators have been normalized. Если пропущена Замыкающая косая черта (или обратная косая черта), она не добавляется и влияет на сравнение. If a trailing slash (or backslash) is missing, it isn’t added, and that affects the comparison. В следующем примере показано, как выполняется сравнение значений пути: The following example demonstrates how path values compare:

Для запуска этого кода вставьте его в полный пример выше перед main и раскомментируйте строку, которая вызывает его в основном объекте. To run this code, paste it into the full example above before main and uncomment the line that calls it in main.

Преобразование между типами пути и строки Converting between path and string types

Объект path может быть неявно преобразован в std::wstring или std::string . A path object is implicitly convertible to std::wstring or std::string . Это означает, что можно передать путь к таким функциям wofstream::open , как, как показано в следующем примере: It means you can pass a path to functions such as wofstream::open , as shown in this example:

Итерация по каталогам и файлам Iterating directories and files

Заголовок предоставляет directory_iterator тип для итерации по отдельным каталогам и recursive_directory_iterator класс для рекурсивного прохода по каталогу и его подкаталогам. The header provides the directory_iterator type to iterate over single directories, and the recursive_directory_iterator class to iterate recursively over a directory and its subdirectories. После создания итератора путем передачи ему объекта path итератор указывает на первое значение directory_entry в пути. After you construct an iterator by passing it a path object, the iterator points to the first directory_entry in the path. Создайте конечный итератор путем вызова конструктора по умолчанию. Create the end iterator by calling the default constructor.

При итерации по каталогу существует несколько типов элементов, которые можно обнаружить. When iterating through a directory, there are several kinds of items you might discover. К этим элементам относятся каталоги, файлы, символические ссылки, файлы сокетов и др. These items include directories, files, symbolic links, socket files, and others. directory_iterator Возвращает свои элементы в виде directory_entry объектов. The directory_iterator returns its items as directory_entry objects.

Setting Library path for win32 console applications

I am getting «dll not found:restarting the application may fix the problem» error when i try to execute a simple «HelloWorld» win32 console application. I know the location of the .dll. How to specify its location when executing the .exe from command prompt?

PS: copying the .dll to the .exe’s current dir seems to solve the problem, but this approach is not suitable in this case.

4 Answers 4

DLL loading happens deep in the plumbing of windows.

If the DLL is not found in the same directory as the application, the PATH is automatically scanned in order to find the directory.

So, the simplest answer to your problem is to add the directory containing the DLL to your PATH. Depending on when the DLL needs to be loaded by your code, you may be able to (temporarily) modify the PATH from inside your «HelloWorld» application.

Читайте также:  Microsoft windows error messages

To manually, permanently add your path to Windows PATH (permanently = until you remove it), right click My Computer>Properties>Advanced>Environment Variables>System Variables>Path>Edit>Variable Value, add a semicolon (which means «in addition to all before») and paste the full path of your dll.

Windows will search the path every time it can’t find something in the current directory.

The documentation for LoadLibraryEx has some discussion on how Windows searches for your dll. You might try using the LOAD_WITH_ALTERED_SEARCH_PATH flag if you can construct a full path to your DLL or use the SetDllDirectory function to add a directory to the search path.

With both implicit and explicit linking, Windows first searches for «known DLLs», such as Kernel32.dll and User32.dll. Windows then searches for the DLLs in the following sequence:

The directory where the executable module for the current process is located.

The current directory.

The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.

The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.

The directories listed in the PATH environment variable.

Is there any way to simulate LD_LIBRARY_PATH in Windows?

I have a program do so some graphics. When I run it interactively, I want it to use OpenGL from the system to provide hardware accelerated graphics. When I run it in batch, I want to be able to redirect it to use the Mesa GL library so that I can use OSMesa functionality to render to an offscreen buffer. The OSMesa functionality is enabled by doing a LoadLibrary/GetProcAddress if the batch start up option is selected.

On Linux, its fairly easy to make this work. By using a wrapper script to invoke the program, I can do something like this:

It is possible to do something this in Windows?

When I try adding a directory to the PATH variable, the program continues to go to the system opengl32.dll. The only way I can get the program to use the Mesa GL/OSMesa shared libraries is to have them reside in the same directory as my program. However, when I do that, the program will never use the system opengl32.dll.

4 Answers 4

If I’ve understood what you’re saying correctly, the wrong version of opengl32.dll is being loaded when your process starts up, i.e., load-time dynamic linking. There is probably no good way to solve your problem without changing this.

You say you can’t use conveniently use run-time dynamic linking (LoadLibrary/GetProcAddress) for opengl32.dll because the calls to it are coming from the Qt library. I presume that the Qt library is itself dynamically linked, however, so you should be able to solve your problem by using run-time linking for it. In this scenario, provided you load opengl32.dll before you load the Qt library, you should be able to explicitly choose which version of opengl32.dll you want to load.

You might want to consider using delayed loading in order to simplify the process of moving from load-time to run-time linking. In this scenario, the first call into the Qt library causes it to be loaded automatically, and you’ll just need to explicitly load opengl32.dll first.

There are a few ways you could handle this, depending on the libraries and their names/locations:

If both have the same name (opengl32.dll), then you need to add the Mesa DLL location to the search path such that it is searched before the system directory. The order directories are checked in is detailed here. As you can see, $PATH comes last, after system, so you can’t just add the directory to that. However, you can make use of the second step («The current directory») by setting the working directory to a path containing the mesa files. Generally this means starting the application using an absolute path while in the directory containing the files.

Читайте также:  Batch файлов системы windows

That’s still not particularly pleasant, though. If you can, you should use LoadLibrary and check for an environment variable ( OPENGL_LIBRARY_PATH ) when your app starts up. Assuming the exports from opengl32.dll and Mesa’s DLL are the same, you can do something like:

This will work perfectly fine, doing almost exactly what you want.

However, if you want to do that, you can’t import opengl32.dll , which you’re probably doing, you have to dynamically link throughout. Make sure not to link against opengl32.lib and you should be fine. Depending on how many functions you use, it may be a pain to set up, but the code can easily be scripted and only needs done once, you can also use static variables to cache the results for the lifetime of the program. It’s also possible to use different function names for different libraries, although that takes a bit more logic, so I’ll leave the details to you.

How to specify preference of library path?

I’m compiling a c++ program using g++ and ld . I have a .so library I want to be used during linking. However, a library of the same name exists in /usr/local/lib , and ld is choosing that library over the one I’m directly specifying. How can I fix this?

For the examples below, my library file is /my/dir/libfoo.so.0 . Things I’ve tried that don’t work:

  • my g++ command is g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
  • adding /my/dir to the beginning or end of my $PATH en` variable
  • adding /my/dir/libfoo.so.0 as an argument to g++

5 Answers 5

Add the path to where your new library is to LD_LIBRARY_PATH (it has slightly different name on Mac . )

Your solution should work with using the -L/my/dir -lfoo options, at runtime use LD_LIBRARY_PATH to point to the location of your library.

..implications.
Security: Remember that the directories specified in LD_LIBRARY_PATH get searched before(!) the standard locations? In that way, a nasty person could get your application to load a version of a shared library that contains malicious code! That’s one reason why setuid/setgid executables do neglect that variable!
Performance: The link loader has to search all the directories specified, until it finds the directory where the shared library resides – for ALL shared libraries the application is linked against! This means a lot of system calls to open(), that will fail with “ENOENT (No such file or directory)”! If the path contains many directories, the number of failed calls will increase linearly, and you can tell that from the start-up time of the application. If some (or all) of the directories are in an NFS environment, the start-up time of your applications can really get long – and it can slow down the whole system!
Inconsistency: This is the most common problem. LD_LIBRARY_PATH forces an application to load a shared library it wasn’t linked against, and that is quite likely not compatible with the original version. This can either be very obvious, i.e. the application crashes, or it can lead to wrong results, if the picked up library not quite does what the original version would have done. Especially the latter is sometimes hard to debug.

Use the rpath option via gcc to linker — runtime library search path, will be used instead of looking in standard dir (gcc option):

This is good for a temporary solution. Linker first searches the LD_LIBRARY_PATH for libraries before looking into standard directories.

If you don’t want to permanently update LD_LIBRARY_PATH you can do it on the fly on command line:

You can check what libraries linker knows about using (example):

And you can check which library your application is using:

Оцените статью