Информация об изменениях

Сообщение Re: Путь к Dll в проекте Visual Studio от 11.08.2019 11:14

Изменено 11.08.2019 11:18 kov_serg

Re: Путь к Dll в проекте Visual Studio
Здравствуйте, ahaos, Вы писали:

A>Как прописать путь к сопутствующим программе Dll, чтобы при запуске скомпилированной программы из Visual Studio (Visual C++) не было сообщений, что они не найдены.

A>Интересует, чтобы это было сделано средствами Visual Studio и относилось к конкретному проекту и путь к Dll был именно произвольно заданным.

A>1. Я Принципиально не хочу держать dll в папке с проектом.

A>2. Принципиально не хочу использовать глобальную переменную PATH.
  Предположим есть приложение main.exe которое хочет библиотеку add.dll
main.cpp
// main.cpp
#include <stdio.h>

extern "C" __declspec(dllimport) int __stdcall add(int x,int y);

int main(int argc,char** argv) {
    int r=add(1,2);
    printf("add(1,2)=%d\n",r);
    return 0;
}

add.cpp
// add.cpp
#include <windows.h>

extern "C" __declspec(dllexport) int __stdcall add(int x,int y) { return x+y; }
int DllMain(HINSTANCE instance,DWORD reason,LPVOID reserved) { return 1; }

build.cmd
cl add.cpp /LD
cl main.cpp /link /SUBSYSTEM:CONSOLE add.lib
Для того что бы оно схавало dll из директории libs надо разместить файлы таким образом:
  main.exe
бинарник от main.cpp
  main.exe.config
<configuration><windows><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="libs"/>
</assemblyBinding></windows></configuration>
  main.exe.manifest
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity name="main" type="win32" version="1.0.0.0" processorArchitecture="x86"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity name="add.dll" type="win32" version="1.0.0.0" processorArchitecture="x86" language="*"/>
        </dependentAssembly>
    </dependency>
</assembly>
  libs/add.dll
бинарник от add.cpp
  libs/add.dll.manifest
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity name="add.dll" version="1.0.0.0" processorArchitecture="x86" type="win32"/>
    <file name="add.dll"/>
</assembly>

После чего можно запукать main.exe

ps: Винда манифесты кэширует так что после изменений надо запустить без манифеста и потом опять с манифестом иначе она будет брать данные не из файлов, а из своего кэша. Всё это безобразие работает начиная с win7. Все эти манифесты можно втолкать в бинарники, что бы было меньше файлов.

pps: для отладки можно использовать такой костыль
  sxs-debug.cmd
start "" cmd /c "ping localhost -n 2 >nul && main.exe || pause"
sxstrace trace -logfile:sxstrace.etl 
sxstrace parse -logfile:sxstrace.etl -outfile:sxstrace.txt 
del sxstrace.etl 
start notepad sxstrace.txt
Re: Путь к Dll в проекте Visual Studio
Здравствуйте, ahaos, Вы писали:

A>Как прописать путь к сопутствующим программе Dll, чтобы при запуске скомпилированной программы из Visual Studio (Visual C++) не было сообщений, что они не найдены.

A>Интересует, чтобы это было сделано средствами Visual Studio и относилось к конкретному проекту и путь к Dll был именно произвольно заданным.

A>1. Я Принципиально не хочу держать dll в папке с проектом.

A>2. Принципиально не хочу использовать глобальную переменную PATH.
  Предположим есть приложение main.exe которое хочет библиотеку add.dll
main.cpp
// main.cpp
#include <stdio.h>

extern "C" __declspec(dllimport) int __stdcall add(int x,int y);

int main(int argc,char** argv) {
    int r=add(1,2);
    printf("add(1,2)=%d\n",r);
    return 0;
}

add.cpp
// add.cpp
#include <windows.h>

extern "C" __declspec(dllexport) int __stdcall add(int x,int y) { return x+y; }
int DllMain(HINSTANCE instance,DWORD reason,LPVOID reserved) { return 1; }

build.cmd
cl add.cpp /LD
cl main.cpp /link /SUBSYSTEM:CONSOLE add.lib
Для того что бы оно схавало dll из директории libs надо разместить файлы таким образом:
  main.exe
бинарник от main.cpp
  main.exe.config
<configuration><windows><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="libs"/>
</assemblyBinding></windows></configuration>
  main.exe.manifest
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity name="main" type="win32" version="1.0.0.0" processorArchitecture="x86"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity name="add.dll" type="win32" version="1.0.0.0" processorArchitecture="x86" language="*"/>
        </dependentAssembly>
    </dependency>
</assembly>
  libs/add.dll
бинарник от add.cpp
  libs/add.dll.manifest
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity name="add.dll" version="1.0.0.0" processorArchitecture="x86" type="win32"/>
    <file name="add.dll"/>
</assembly>

После чего можно запуcкать main.exe

ps: Винда манифесты кэширует так что после изменений надо запустить без манифеста и потом опять с манифестом иначе она будет брать данные не из файлов, а из своего кэша. Всё это безобразие работает начиная с win7. Все эти манифесты можно втолкать в бинарники, что бы было меньше файлов.

pps: для отладки можно использовать такой костыль
  sxs-debug.cmd
start "" cmd /c "ping localhost -n 2 >nul && main.exe || pause"
sxstrace trace -logfile:sxstrace.etl 
sxstrace parse -logfile:sxstrace.etl -outfile:sxstrace.txt 
del sxstrace.etl 
start notepad sxstrace.txt