2009-10-15 4 views
2

В настоящее время я создаю свою собственную фреймворк в C++ (MSVS 2008), которая экспортирует DLL с кучей функций для пользователя моей инфраструктуры для использования/вызова. В начале, когда мой проект все еще был небольшим, все работало нормально. Я собрал свой проект. Выделились MyFramework.dll и MyFramework.lib. Я притворился пользователем; поместите файл MyFramework.dll в папку «Отладка» моего нового проекта VS, поместите файл MyFramework.lib и MyFramework.h в мою папку проекта, # include-d MyFramework.h в моем коде и voilá, я мог бы назвать (все еще простой) в рамках моего нового проекта.Создание dll, который ссылается на другую dll (MSVS2008 C++)

Но теперь я расширил рамки. Теперь он использует собственную внешнюю dll (позвольте мне называть Graphics.dll) и включил ее так же (DLL в папку Debug, .lib/.h в папке проекта, #include Graphics.h в коде).

Проблема заключается в том, что когда я создаю MyFramework.dll/MyFramework.lib, включите его в свой новый проект и постройте, компоновщик жалуется, что не смог включить Graphics.h, который, очевидно, был включен в MyFramework.dll где-то.

Так что мой вопрос. Я хотел бы, чтобы пользователь MyFramework.dll должен был включать файлы MyFramework. * В свой проект и не нуждался в копировании/вставке всех внешних библиотек, которые я решил использовать в MyFramework. Как я могу это сделать? Я взглянул на this thread. В нем говорится о добавлении существующего элемента и нажатии маленькой стрелки рядом с кнопкой «Добавить», но ... стрелка в моей версии MSVS отсутствует ...

Помощь очень ценится.

Сердечные приветы В. Спек

+1

линкером, жалующимся на файл включения? ни за что! – stijn

+0

Вы правы, это компилятор. –

ответ

1

«Проблема заключается в том, что, когда я Создать MyFramework.dll/MyFramework.lib, включить его в моем новом проекте и строить, компоновщик жалуется не в состоянии включить графики .h, который, очевидно, был включен в MyFramework.dll где-нибудь ».

Вы указали путь к файлу заголовка? Компилятор сообщает, что заголовочный файл не находится в том же каталоге, что и файл cpp, который был преобразован, и его также не указаны в дополнительных каталогах include.

Перейти к Проект-> Свойства, затем выберите C/C++

Первый вариант вы увидите, как "Additional Include Directories". Вам нужно поместить путь в свой заголовок Graphics.h туда, а также с любыми другими путями, требуемыми для каждой разделенной запятой. Проект, который я открывал в mo, имеет, например: «../AudioLibrary;..CoreLibrary;»

Редактировать: Из ваших комментариев к посту Марка вы говорите, что вы хотите, чтобы встроить Graphics.DLL в вашей DLL. Мой ответ таков:

Если у вас нет исходного кода для Graphics.dll, у вас возникнет проблема. То, что вы просите, возможно, но ОЧЕНЬ сложно сделать. В принципе вы не можете использовать LoadLibrary. Вы будете вынуждены написать свой собственный для LoadLibaray и GetProcAddress, который будет смотреть на встроенную DLL, а не пытаться найти его на диске ... Его можно сделать, но вам нужно будет много читать на Portable Executable (PE) file structure.

+0

И это точно связывает то, что я не хочу делать. Что я могу сделать в своем проекте «MyFramework», чтобы не включать внешние файлы в мой новый проект, который использует MyFramework.dll? –

+0

Ну, вам нужно знать, как выглядит прототип функции. Использование GetProcAddress, как было предложено Марком, хорошо и хорошо, но вам нужно создать файл заголовка, который имеет копию материала в Graphics.h, или вы должны включить оригинальный Graphics.h. В противном случае, как компилятор может знать, какие параметры необходимы? – Goz

+0

Я также должен указать, что если вы собираетесь использовать GetProcAddress, вам нужно создать кучу правильных указателей функций с соответствующим прототипом функции, встроенным в указатель. – Goz

0

Если вы не хотите, чтобы пользователь имел или включал Graphics.h, один из способов - использовать LoadLibrary для динамической загрузки Graphics.dll во время выполнения.

Это будет означать, что пользователь сможет скомпилировать MyFramework без Graphics.dll, поэтому было бы разумно сделать какие-то сообщения об ошибках, если LoadLibrary терпит неудачу.

После того, как вы успешно вызвали LoadLibrary на Graphics.dll, вам нужно вручную импортировать каждую функцию (и ее подпись) с помощью GetProcAddress - это фактически даст вам указатели на функции. Как вы храните указатели на функции, зависит от вас; Обычно я предпочитаю обертывать класс вокруг импортированных функций, но нет ничего, что помешает вам сохранить указатели на функции в глобальной области.


Как уже упоминалось в комментариях, если вы не хотите, чтобы распространять Graphics.dll на все, что нужно будет создать статическую библиотеку (то есть «встроенный» в MyFramework.dll). Если вы do хотите распространять Graphics.dll (так что пользователь может использовать Graphics.dll без MyFramework.dll), то вышеописанный подход остается лучшим вариантом. На самом деле вышеприведенный подход предполагает, что вы распространяете Graphics.dll с MyFramework.dll, но у пользователя может не быть доступного Graphics.h.

+0

Но, вероятно, пользователю все равно понадобится отдельная копия Graphics.dll где-нибудь на его жестком диске, верно? Это тоже нежелательная ситуация. Пользователь не должен знать о существовании Grpahics.dll. Ему нужно только заботиться о файлах MyFramework. * ... –

+0

Вы говорите о встраивании DLL в исполняемый файл? Если это так, используйте статическую библиотеку, а не динамическую библиотеку! – Goz

+0

Да, я говорю о встраивании Graphics.dll в MyFramework.dll. Итак, предложение представляет собой статическую библиотеку? Но что вы имеете в виду? сделайте библиотеку MyFramework статичной или каким-то образом включите статическую графическую библиотеку в MyFramework.dll. Пожалуйста, обратите внимание, что у меня нет исходного кода для Graphics.dll, за исключением Graphics.h. –

2

Что происходит, пользователь включает один из файлов заголовков вашей библиотеки. Затем этот файл включает в себя «graphics.h». Если вы не хотите, чтобы ваши пользователи имели доступ к этому файлу, вы должны скрыть его из интерфейса ваших библиотек.

Это ваша библиотека должна иметь общедоступные заголовочные файлы api и частные файлы заголовка реализации. Ваш пользователь включает только заголовочные файлы public api, они не включают сторонние или частные файлы include. Когда эти файлы ссылаются на частные типы или сторонние типы, они могут использовать только указатели или ссылки, они объявляются вперед. Это позволяет частной части класса использовать частный библиотечный код и сторонние типы.

Вероятность использования Pimpl Idiom исправит это для вас.

+0

Я думаю, что вы можете быть правы. Прямо сейчас я включаю Graphics.h в заголовочный файл интерфейса MyFramework.h. Это не верно. Я также поговорил с моим руководителем, который сказал мне то же самое.Вот почему компилятор пользователя жалуется на отсутствие файла Graphics.h. Я посмотрю на шаблон PIMPL и посмотрю, смогу ли я исправить свою проблему. Придется сделать это немного позже, хотя. Я вернусь к окончательному решению. –

+0

Я пытался использовать неуправляемую библиотеку из управляемой DLL, используя C++/CLI. К сожалению, мой заголовок использовал заголовок OpenCV, что означало необходимость создания смешанного режима, который бы не работал. Использование идиомы Pimpl было именно тем, что мне было нужно – Fuzz

Смежные вопросы