![]() |
Передача указателя на интерфейс через DLL
Есть класс, в котором есть некоторые методы и члены-интерфейсы, с которыми надо работать. Сами классы находятся в заголовочном файле, их реализация в исходнике. Все это собрано в библиотеку и подключено к другому проекту. Во время работы с проектом любое использование интерфейса из подключенной библиотеки приводит к ошибке доступа к памяти.
Может указатели на интерфейсы надо тоже как-то передавать по-особенному, как методы, например? Код:
class Shader Заранее огромное спасибо за помощь. |
Ответ: Передача указателя на интерфейс через DLL
для клиентского кода должно быть __declspec(dllimport).
определи дефайн для проекта своей библиотеки. например MY_SUPERLIB. определи макрос типа: Код:
#ifdef MY_SUPERLIB Код:
SUPERLIB_API HRESULT loadShader(LPCSTR,LPCSTR,LPCSTR); |
Ответ: Передача указателя на интерфейс через DLL
К сожалению, безрезультатно.
Абсолютно никакой реакции на данные манипуляции не возникло. Только предупреждение выдает: Код:
несовместимая компоновка dll В заголовок библиотеки добавил Код:
#ifdef MY_SUPERLIB И все, никаких изменений в основном проекте я не производил. UPD: Добавил #define MY_SUPERLIB к проекту - никакой реакции. |
Ответ: Передача указателя на интерфейс через DLL
пока не понятно. такто код рабочий.
проверь на функции. создай функцию тупо возвращающую инт и посмотри как она будет линковаться. |
Ответ: Передача указателя на интерфейс через DLL
Как проверить линкование функции?
По-моему дело в интерфейсах. С ними косяки, остальные функции нормально работали и раньше. |
Ответ: Передача указателя на интерфейс через DLL
хм. странно. как они работали без dllimport-а.
покажи как используешь. |
Ответ: Передача указателя на интерфейс через DLL
Проект библиотеки:
Файл заголовка: Код:
class Shader Код:
HRESULT Shader::loadShader(LPCSTR sourse, LPCSTR point, LPCSTR version) Код:
diffuse.loadShader("VertexShader.hlsl", "main","vs_1_1"); Кстати, во время ошибки вылазит некоторая служебная информация от студии. Там указаны значения каждого из объектов. Что странно - вроде в объекте шейдера все в порядке, а вот объект Device всегда содержит 0x00000000. ![]() |
Ответ: Передача указателя на интерфейс через DLL
Хочется спать, потому же нет состояния разобраться в коде, но смазанные воспоминания и обронённое упоминание компоновки поднимает следующее (если ничего не даст - не серчать):
Соглашение вызова ("Во время работы с проектом любое использование интерфейса из подключенной библиотеки приводит к ошибке доступа к памяти.")? coff omf ("несовместимая компоновка ")? декорирование? |
Ответ: Передача указателя на интерфейс через DLL
один хидер - соглашение вызова одинаковое, + автор говорил что на обычных функциях это работает. хотя глянуть настройки компилятора в проекте таки можно.
один компилятор - совместимая компоновка и одинаковое декорирование. поставь точку останова в начало loadShader, посмотри доходит ли твоя программа до туда. |
Ответ: Передача указателя на интерфейс через DLL
Да, доходит до начала загрузки шейдера.
Потом, после загрузки его из файла, значения интерфейсов никак не меняются. ![]() Попробовал создавать указатель на интерфейс прямо в программе - работает. Попробовал в тестирующем приложении обратиться к указателю на интерфейс Device, который содержится в заголовке, - не разрешает. UPD: Господа, все прекрасно работает с некоторыми исправлениями. HolyDel, я преклоняюсь перед твоим опытом, но боюсь, что для корректной работы приложения нужно было написать в заголовке следующее: Код:
#ifdef MY_SUPERLIB А так же просто добавить спецификатор SUPERLIB_API к главному интерфейсу приложения. Как оказалось - это то, что было нужно. Спасибо огромное за помощь. Что бы я без вас делал. |
Ответ: Передача указателя на интерфейс через DLL
чйорт! что ты понимаешь под указателями на интерфейс? что значит "значения интерфейсов никак не меняются. "?
раз метод вызывается - значит с линковкой все в порядке. this нормальный. может метод кривой? и почему у тебя shader - типа твой Shader, а не дх-ский? |
Ответ: Передача указателя на интерфейс через DLL
Эй, DarkMedveD, твой главный косяк в отсутствии нормального конструктора класса Shader. Ты не зануляешь указатели, в частности errorBuffer. В итоге если функция D3DXCompileShaderFromFile завершается нормально, буфер по переданному ей указателю не создается. А после функции у тебя сразу стоит if ( errorBuffer ), который сработает если у тебя в errorBuffer будет мусор, и далее вызовется Release несуществующего буфера.
Я думаю в твоем проекте уместно разделить реализацию и интерфейс. Например сделать абстрактный класс и от него наследовать класс реализацию. В абстрактном классе сделать только методы ( чисто виртуальные ). А в реализацию уже добавить все данные-члены. Добавить функцию которая будет создавать объект типа Реализация, но возвращать указатель на класс типа Интерфейс. Так как в этом случае будет использоваться RTTI то указывать dllexport вообще не понадобиться. Ну или найти другие паттерны которые делают интерфейс и реализацию раздельно. У тебя сейчас очень плохо - класс вообще не защищен, и пользователь может его испортить как угодно. |
Ответ: Передача указателя на интерфейс через DLL
Код:
Я думаю в твоем проекте уместно разделить реализацию и интерфейс. + можно будет не подулючть дх к результирующему проекту (не надо будет ставить дхсдк) |
Ответ: Передача указателя на интерфейс через DLL
Цитата:
Цитата:
|
Ответ: Передача указателя на интерфейс через DLL
У меня, парни, так и сделано.
Когда создается объект класса Shader все его переменные обнуляются, с чего вы взяли, что у меня нет конструктора? Так же есть и класс, от которого все наследуется, только он никак не относится к шейдерам. От него я наследую все объекты сцены. А виртуальные методы, свои интерфейсы и все те вкусные штуки, о которых вы говорили - пока слишком сложно для меня. Спасибо за советы, я постараюсь прислушаться. Если соображалки хватит. |
Часовой пояс GMT +4, время: 19:26. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot