Я хочу использовать неявное связывание в своем проекте, а nmake действительно нужен файл .def. Проблема в том, что это класс, и я не знаю, что писать в разделе экспорта. Может ли кто-нибудь указать мне правильное направление?
Сообщение об ошибке следующее:
NMAKE: U1073: не знаю, как сделать DLLCLASS.def
P.S: Я пытаюсь построить с помощью Windows CE Platform Builder.





Если я правильно помню, вы можете использовать __declspec(dllexport) на класс, и VC++ автоматически создаст экспорт для всех символов, связанных с классом (конструкторы / деструкторы, методы, vtable, typeinfo и т. д.).
У Microsoft есть дополнительная информация об этом здесь.
Или экспортируйте только те символы, которые вам нужны. связь
Решение следующее:
поскольку класс экспортируется, вам также необходимо добавить экспортируемые методы в файл .def
Я не узнал, как экспортировать конструктор, поэтому решил использовать фабричный метод (статический), который вернет новые экземпляры объекта.
другие функции будут экспортированы путем добавления обычного объявления экспорта в файл .def.
Надеюсь, кому-то будет полезна эта информация.
это не решение, а обходной путь. Вы может добавляете символ конструктора в файл .def.
Вы всегда можете найти декорированное имя для функции-члена, используя мусорная корзина / symbols myclass.obj
в моем случае
class A {
public:
A( int ){}
};
дамп dumpbin показал символ ??0A@@QAE@H@Z (public: __thiscall A::A(int))
Помещение этого символа в файл .def заставляет компоновщик создавать символ A :: A (int) в символах экспорта.
НО!, как утверждает @paercebal в своем комментарии: ручной ввод декорированных (искаженных) имен - это рутинная работа, подверженная ошибкам, и, к сожалению, не гарантируется переносимость между версиями компилятора.
Я нашел лучший путь - это абстрактная фабрика.
Начнем с определения чисто виртуального базового класса. Это класс без реализации, чисто виртуальный интерфейсный класс.
Вы можете экспортировать этот виртуальный базовый класс «абстрактного интерфейса», но для этого нет реальной причины. Когда вызывающий абонент использует его, он будет использовать его через указатель (PImpl или указатель на реализацию), поэтому все, о чем он знает, - это простой адрес памяти. Файл Def, хотя и требует немного больше работы, но дает преимущества, превосходящие то, что может получить __declspec (dllexport). Какие преимущества, спросите вы? Мы до этого доберемся, подожди.
Сделайте так, чтобы ваш настоящий класс был публично унаследован от виртуальной базы. Теперь создайте фабричный метод для создания вашего объекта и вызываемый деструктор «выпускать» для выполнения очистки. Назовите эти методы примерно как «ConstructMyClass» и «ReleaseMyClass». Пожалуйста, замените "Мои занятия" :-)
Эти методы factory / release должны принимать только типы POD, если им нужны какие-либо параметры (простые-старые данные: целое число, char и т. д.). Тип возвращаемого значения должен быть базовым классом вашего виртуального абстрактного интерфейса или, скорее, указателем на него.
IMyClass * CreateAnObjectOfTypeIMyClass ();
Возможно, теперь очевидно, зачем нам виртуальный базовый класс? Поскольку класс виртуального интерфейса не имеет реализации, он по существу все типы POD (sort-of), поэтому «тип данных» класса может быть понят большинством вызывающих, таких как Visual Basic, C или совершенно разные компиляторы C++.
Если вы достаточно наворочены, вы можете обойтись без метода "ручной выпуск" (извините, пришлось это сделать). Как? Управляйте своими собственными ресурсами в классе с помощью интеллектуальных указателей и архитектуры типа pImpl, чтобы, когда объект умирает, он убирался за собой. Это означает, что ваш класс, по бессмертным словам нашего святого и спасителя Скотт Мейерс, "легко использовать правильно и сложно использовать неправильно", позволяет вызывающему игнорировать необходимость очистки. Пусть те из нас, кто никогда не забывал называть «.Закрыть», бросят первый камень.
Может, эта архитектура звучит знакомо? Должен, это в основном версия COM для микромашин. Ну, вроде как, по крайней мере, концепция интерфейса, заводское построение и выпуск.
В конце концов, вы экспортировали интерфейс для своего класса, создали (и экспортировали) методы Создавать и Разрушать, и теперь вызывающие абоненты могут вызывать вашу фабричную функцию PleaseConstructMyClass, чтобы ваша DLL возвращала полностью сконструированный, полностью реализованный и полностью запеченный объект под видом его интерфейса. Они могут вызывать все общедоступные методы вашего класса (по крайней мере, те, что находятся в абстрактном виртуальном интерфейсе) и делать все самое интересное.
Когда они закончат с объектом, который был возвращен фабричной функцией, они могут вызвать функцию «ReleaseMyClass», чтобы попросить вашу DLL очистить ресурсы объекта, или вы можете помочь им, заставив свой класс очистить себя, сделав метод "ReleaseMyClass" избыточен и бесполезен.
Если кого-то интересуют конкретные выгоды и компромиссы для использования файла Def и интерфейса (помимо моего слепого заявления), пожалуйста, сообщите об этом, и мы сможем копать глубже.
Разве тебе не нравятся эти вещи?
Вау, какое чтение, я бы с удовольствием разобрался с файлами DEF. Кроме того, у вас не было бы примера кода, реализующего эту архитектуру? Это интересно, но код всегда легче увидеть, чем перевести его с английского ха-ха
Разве использование классов STL, таких как unique_ptr, shared_ptr, string и vector в качестве возвращаемых или аргументных типов, не нарушит совместимость всех кросс-компиляторов (подумайте, MSVC-MinGW)?
Использование файла .DEF - худший способ экспортировать код C++. Я надеюсь, что ключевые слова dllimport / dllexport, описанные Грегом Хьюгиллом, могут быть использованы в вашем случае, как показано этой ссылкой MS: msdn.microsoft.com/en-us/library/ms924233.aspx