2008-10-09 8 views
2

Я хочу использовать неявное связывание в моем проекте, а nmake действительно хочет файл .def. Проблема в том, что это класс, и я не знаю, что писать в разделе экспорта. Может ли кто-нибудь указать мне в правильном направлении?Экспорт DLL C++ класса, вопрос о файле .def

Сообщение об ошибке выглядит следующим образом:

NMAKE: U1073: не знаю, как сделать '' DLLCLASS.def

PS: Я пытаюсь построить с помощью Windows CE Platform Builder ,

+1

Использование файла .DEF является наихудшим способом экспорта кода на C++. Я надеюсь, что ключевые слова dllimport/dllexport, описанные Грегом Хьюджиллом, могут быть использованы в вашем случае, как показано в этой ссылке MS: http://msdn.microsoft.com/en-us/library/ms924233.aspx – paercebal 2008-10-09 20:32:36

ответ

4

Вы всегда можете найти декорированное имя для функции члена с помощью dumpbin/символов myclass.obj

в моем случае

class A { 
    public: 
    A(int){} 
}; 

dumpbin свалка показал символ [email protected]@[email protected]@Z (public: __thiscall A::A(int))

Сведя символ в файле .def заставляет компоновщик создавать символ A :: A (int) в символах экспорта.

НО! как @paercebal заявляет в своем комментарии: ручная запись украшенных (искаженных) имен - это серьезная ошибка, и, к сожалению, она не должна быть переносимой по версиям компилятора.

+0

Спасибо вам большое! Это может быть решение, которое я искал. – Vhaerun 2008-10-10 06:47:52

8

Если я правильно помню, вы можете использовать __declspec(dllexport) на класса и VC++ автоматически создает экспорт для всех символов, относящихся к классу (Конструкторы/деструктор, методы, виртуальные таблицы, TypeInfo и т.д.).

У Microsoft есть дополнительная информация об этом here.

+0

Или экспортируйте только символов, о которых вы заботитесь. [ссылка] (http: // stackoverflow.com/questions/16419318/one-way-of-eliminating-c4251-warning-when-use-stl-classes-in-the-dll-interface/35275889 # 35275889) – 2016-09-12 17:09:33

0

Решение следующее:

  • поскольку класс экспортируется, вам также необходимо добавить экспортируемые методы в .def файле

  • я не нашел, как экспортировать конструктор, поэтому я пошел с использованием фабричного метода (статического), который вернет новые экземпляры объекта

  • Другие функции будут экспортированы путем добавления нормального экспортного объявления в файле .def

Надеюсь, что эта информация будет полезной.

+0

Это не решение, а обходное решение. Вы можете добавить символ конструктора в файл .def. – xtofl 2008-10-09 11:33:20

+0

Все три пулевые точки неверны: см. __Declspec выше. – EJP 2010-03-23 09:16:27

4

Я нашел лучший маршрут для абстрактной фабрики.

Начните с определения чисто виртуального базового класса. Это класс без реализации, чисто виртуальный класс интерфейса.

Вы можете экспортировать этот виртуальный базовый класс «абстрактного интерфейса», но для этого нет никакой реальной причины. Когда вызывающий использует его, они будут использовать его через указатель (PImpl, или указатель на реализацию), так что все, о котором знает вызывающий, - это простой адрес памяти. Файл Def, в то время как teensy бит больше работает, чтобы идти в ногу с ним, обеспечивает преимущества, превышающие возможности __declspec (dllexport).Какие выгоды вы спрашиваете? Мы доберемся до этого, вы просто ждете.

Имейте ваш реальный класс публично наследовать от виртуальной базы. Теперь создайте фабричный метод для создания вашего объекта и «выпуск», вызывающий деструктор ish для выполнения очистки. Назовите эти методы что-то вроде «ConstructMyClass» и «ReleaseMyClass». Пожалуйста, замените «MyClass» :-)

Эти методы изготовления/выпуска должны принимать только типы POD, если им нужны какие-либо параметры (простые-старые-данные: целое число, символ и т. Д.). Тип возврата должен быть вашим виртуальным абстрактным базовым классом интерфейса, точнее, указателем на него.

IMyClass * CreateAnObjectOfTypeIMyClass();

Возможно, теперь очевидно, почему нам нужен виртуальный базовый класс? Поскольку класс виртуального интерфейса не имеет реализации, это, по сути, все типы POD (sort-of), поэтому «тип данных» класса может быть понят большинством абонентов, таких как Visual Basic, C или очень разными компиляторами на C++.

Если вы достаточно причудливы, вы можете обойти необходимость в «ручном выпуске» (извините, пришлось это сделать). Как? Управляйте своими собственными ресурсами в классе с помощью интеллектуальных указателей и типа архитектуры pImpl, поэтому, когда объект умирает, он будет очищаться после себя. Это означает, что ваш класс - это бессмертные слова нашего святого и спасителя Scott Meyers, "easy to use correctly and hard to use incorrectly", позволяя вызывающему персоналу игнорировать необходимость очистки. Пусть те из нас, кто никогда не забывал называть «.close« лить первый камень.

Возможно, эта архитектура звучит знакомо? Должно быть, это в основном микромашинная версия COM. Ну, вроде бы, по крайней мере, концепция интерфейса, заводское строительство и выпуск.

В конце концов вы экспортировали интерфейс для вашего класса, сделанный (и экспортируются) Создание и уничтожить метод, и теперь абоненты могут вызывать вашу PleaseConstructMyClass функции фабрики, чтобы ваша DLL вернуть полностью построена , полностью реализованный и полностью испеченный объект под видом интерфейса. Они могут обращаться ко всем общедоступным методам вашего класса (по крайней мере, те, что относятся к вашему абстрактному виртуальному интерфейсу) и делать все самое интересное.

Когда они закончили с объектом, который был возвращен функцией фабрики, то они могут вызвать «ReleaseMyClass» функцию, чтобы попросить ваш DLL, чтобы очистить ресурсы объекта, или вы можете помочь им вместе, делая ваш класс очищает себя, делая метод «ReleaseMyClass» избыточным и бесполезным.

Если кто-то заинтересован в конкретных выигрышах &, компромисс за использование файла Def и интерфейса (помимо моего слепого слова), пожалуйста, подключитесь, и мы сможем углубиться.

Разве вы не любите этот материал?

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

  • Нет связанных вопросов^_^