Здравствуйте, господа.
Вопрос вынесен в тему, а ситуация такая. Есть некий класс, который основной прогой используется достаточно редко (скажем конвертирует файл из одного формата в другой), или является компонентом, который может устанавливаться опционально. Естественно приходит мысль поместить его код в DLL и грузить при необходимости. Так вот можно ли и как импортировать этот класс из DLL при явном связывании?
Я написал следующий код:
При компиляции получил сообщение типа cannot convert from CMyClass to CMyClass.
Если же просто написать PCMYCLASS(); то линкер говорит что Foo1 Foo2 Foo3 unresolved external symbol.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re: Можно ли импортировать класс из DLL при explicit linkin
Здравствуйте, Gregory, Вы писали:
G>Здравствуйте, господа. G>Вопрос вынесен в тему, а ситуация такая. Есть некий класс, который основной прогой используется достаточно редко (скажем конвертирует файл из одного формата в другой), или является компонентом, который может устанавливаться опционально. Естественно приходит мысль поместить его код в DLL и грузить при необходимости. Так вот можно ли и как импортировать этот класс из DLL при явном связывании?
Из библиотек экспортируются только функции. Но эту задачу можно решить другим способом.
В библиотеке описать экспортируемую функцию, которая будет принимать все необходимые параметры (имена файлов, форматы, опции и т.д.). В этой функции работать со своим классом (он является внутренним классом библиотеки). Вот и все.
Re[2]: Можно ли импортировать класс из DLL при explicit lin
Здравствуйте, molostov, Вы писали:
M>Из библиотек экспортируются только функции. Но эту задачу можно решить другим способом. M>В библиотеке описать экспортируемую функцию, которая будет принимать все необходимые параметры (имена файлов, форматы, опции и т.д.). В этой функции работать со своим классом (он является внутренним классом библиотеки). Вот и все.
неа. из dll можно экспортировать как класс, так и обычную переменную.
оформляется примерно также.
// h-файл#ifdef DLL0_EXPORTS
#define DLL0_API __declspec(dllexport)
#else
#define DLL0_API __declspec(dllimport)
#endif// This class is exported from the dll0.dllclass DLL0_API CDll0 {
public:
CDll0(void);
};
extern DLL0_API int nDll0;
DLL0_API int fnDll0(void);
// cpp-файл
// This is an example of an exported variable
DLL0_API int nDll0=0;
// This is an example of an exported function.
DLL0_API int fnDll0(void)
{
return 42;
}
// This is the constructor of a class that has been exported.
// see dll0.h for the class definition
CDll0::CDll0()
{
return;
}
зы. только зачем же такой экспорт-файл писать загадочный?...
Re[3]: Можно ли импортировать класс из DLL при explicit lin
От:
Аноним
Дата:
06.02.04 02:56
Оценка:
Здравствуйте, Ovl, Вы писали:
Ovl>Здравствуйте, molostov, Вы писали:
M>>Из библиотек экспортируются только функции. Но эту задачу можно решить другим способом. M>>В библиотеке описать экспортируемую функцию, которая будет принимать все необходимые параметры (имена файлов, форматы, опции и т.д.). В этой функции работать со своим классом (он является внутренним классом библиотеки). Вот и все.
Ovl>неа. из dll можно экспортировать как класс, так и обычную переменную. Ovl>оформляется примерно также.
Ovl>
Ovl>// h-файл
Ovl>#ifdef DLL0_EXPORTS
Ovl>#define DLL0_API __declspec(dllexport)
Ovl>#else
Ovl>#define DLL0_API __declspec(dllimport)
Ovl>#endif
Ovl>// This class is exported from the dll0.dll
Ovl>class DLL0_API CDll0 {
Ovl>public:
Ovl> CDll0(void);
Ovl>};
Ovl>extern DLL0_API int nDll0;
Ovl>DLL0_API int fnDll0(void);
Ovl>
Ovl>
Ovl>// cpp-файл
Ovl>// This is an example of an exported variable
Ovl>DLL0_API int nDll0=0;
Ovl>// This is an example of an exported function.
Ovl>DLL0_API int fnDll0(void)
Ovl>{
Ovl> return 42;
Ovl>}
Ovl>// This is the constructor of a class that has been exported.
Ovl>// see dll0.h for the class definition
Ovl>CDll0::CDll0()
Ovl>{
Ovl> return;
Ovl>}
Ovl>
Ovl>зы. только зачем же такой экспорт-файл писать загадочный?...
Вы посмотрите на задание, вернее на ограничения в нем заданные.
DLL не линкуется, а грузится вызовом AfxLoadLibrary. Как в таком случае класс экспортировать?
Re[2]: Можно ли импортировать класс из DLL при explicit lin
Здравствуйте, molostov, Вы писали:
M>Из библиотек экспортируются только функции. Но эту задачу можно решить другим способом. M>В библиотеке описать экспортируемую функцию, которая будет принимать все необходимые параметры (имена файлов, форматы, опции и т.д.). В этой функции работать со своим классом (он является внутренним классом библиотеки). Вот и все.
Спасибо. Именно так я уже и сделал. Хотелось как лучше, а получилось...
Хотя чем собствено функция-мембер отличается от обычной кроме того, что ей через ЕАХ передается this? Да ни чем, и импортировать ее можно, просто писанины много лишней будет.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re[3]: Можно ли импортировать класс из DLL при explicit lin
Здравствуйте, Ovl, Вы писали:
Ovl>Здравствуйте, molostov, Вы писали:
Ovl>неа. из dll можно экспортировать как класс, так и обычную переменную. Ovl>оформляется примерно также.
Ovl>skiped
1) В следующем посте написано, почему такое решение не подходит.
2) Использование dllexport/dllimport практически сводит на нет все преимущества dll.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re[4]: Можно ли импортировать класс из DLL при explicit lin
Здравствуйте, Аноним, Вы писали:
А>Вы посмотрите на задание, вернее на ограничения в нем заданные. А>DLL не линкуется, а грузится вызовом AfxLoadLibrary. Как в таком случае класс экспортировать?
угу. тогда никак. точнее — я не знаю способов экспортировать класс. и поиск мне ничего пока не принес.
а экспортирование функций a-la "я из класса" с явным аргументом указателя на класс — это все же не то...
Здравствуйте, Ovl, Вы писали:
G>>2) Использование dllexport/dllimport практически сводит на нет все преимущества dll.
Ovl>можно узнать какие именно преимущества сводятся на нет?
MSDN/.../DLLs/Exporting from a DLL/Determining Which Exporting Method to Use
1. Экспорт с использованием DEF, позволяет вносить изменения в DLL, без пересборки основной программы (если конечно при этом не изменяются интерфейсы классов и функций).
2. Экспорт с использованием DEF, позволяет осуществлять explicit linking, что очень удобно, когда например к-либо часть кода используется только по большим праздникам.
3. Если ни чего из вышеуказанного не требуется, то использование dllexport/dllimport имеет смысл только в том случае, если несколько PE (DLL/EXE) узают одну и ту же DLL. В противном случае нет ни какой разницы между использованием DLL и включением ее кода (либо в исходникакх, либо в объектниках) в основную прогу.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re[6]: Можно ли импортировать класс из DLL при explicit lin
Здравствуйте, Gregory, Вы писали:
G>MSDN/.../DLLs/Exporting from a DLL/Determining Which Exporting Method to Use
ммм...
G>1. Экспорт с использованием DEF, позволяет вносить изменения в DLL, без пересборки основной программы (если конечно при этом не изменяются интерфейсы классов и функций). G>2. Экспорт с использованием DEF, позволяет осуществлять explicit linking, что очень удобно, когда например к-либо часть кода используется только по большим праздникам. G>3. Если ни чего из вышеуказанного не требуется, то использование dllexport/dllimport имеет смысл только в том случае, если несколько PE (DLL/EXE) узают одну и ту же DLL. В противном случае нет ни какой разницы между использованием DLL и включением ее кода (либо в исходникакх, либо в объектниках) в основную прогу.
итого
.DEF
Exporting functions in a .DEF file gives you control over what the export ordinals are. When you add additional exported functions to your DLL, you can assign them higher ordinal values (higher than any other exported function)
я например привык писать .def даже при __declspec(dllexport). просто привычка. смотрится приятней. кроме того тогда удобнее и явно библиотечку подгружать.
Another advantage to using a .DEF file is that you can export functions using the NONAME attribute, which places only the ordinal in the exports table in the DLL. For DLLs with a large number of exported functions, using the NONAME attribute can reduce the size of the DLL file
то бишь использование __declspec(dllexport) не мешает явно получать доступ к библиотеке, .DEF и dllexport могут существовать вместе — это не проблема.
поскольку я тупой до невозможности, то повторяю свой вопрос:
какие именно преимущества сводятся на нет при использовании спецификаторов dllexport/dllimport?
Здравствуйте, Gregory, Вы писали:
G>Спасибо. Именно так я уже и сделал. Хотелось как лучше, а получилось...
Получилось отлично (лучше и проще варианта наверное нет).
G>Хотя чем собствено функция-мембер отличается от обычной кроме того, что ей через ЕАХ передается this? Да ни чем, и импортировать ее можно, просто писанины много лишней будет.
Функцию импортировать можно, это железно. Но весь класс, чтобы им полноценно пользоваться — это вряд ли (только по частям). Ведь экспорт/импорт был использован еще до реализации ООП.
Re[3]: Можно ли импортировать класс из DLL при explicit lin
Здравствуйте, Ovl, Вы писали:
Ovl>неа. из dll можно экспортировать как класс, так и обычную переменную.
Насчет переменной, согласен, просто не упомянул. А вот класс — нельзя. Экспортировать можно функции класса, вплоть до его конструктора, с помощью которого можно создать объект (лично не проверял, но так говорят ). Но какой смысл в объекте, если не известно, что он умеет делать.
Re[7]: Можно ли импортировать класс из DLL при explicit lin
Здравствуйте, Ovl, Вы писали:
Ovl>Здравствуйте, Gregory, Вы писали:
G>>MSDN/.../DLLs/Exporting from a DLL/Determining Which Exporting Method to Use Ovl>ммм...
G>>1. Экспорт с использованием DEF, позволяет вносить изменения в DLL, без пересборки основной программы (если конечно при этом не изменяются интерфейсы классов и функций). G>>2. Экспорт с использованием DEF, позволяет осуществлять explicit linking, что очень удобно, когда например к-либо часть кода используется только по большим праздникам. G>>3. Если ни чего из вышеуказанного не требуется, то использование dllexport/dllimport имеет смысл только в том случае, если несколько PE (DLL/EXE) узают одну и ту же DLL. В противном случае нет ни какой разницы между использованием DLL и включением ее кода (либо в исходникакх, либо в объектниках) в основную прогу.
Ovl>итого
Ovl>.DEF Ovl>
Exporting functions in a .DEF file gives you control over what the export ordinals are. When you add additional exported functions to your DLL, you can assign them higher ordinal values (higher than any other exported function)
Ovl>я например привык писать .def даже при __declspec(dllexport). просто привычка. смотрится приятней. кроме того тогда удобнее и явно библиотечку подгружать.
Ovl>
Another advantage to using a .DEF file is that you can export functions using the NONAME attribute, which places only the ordinal in the exports table in the DLL. For DLLs with a large number of exported functions, using the NONAME attribute can reduce the size of the DLL file
Ovl>сомнительный аргумент... Ovl>---------------------------------------------------------------------------------------------
Ovl>то бишь использование __declspec(dllexport) не мешает явно получать доступ к библиотеке, .DEF и dllexport могут существовать вместе — это не проблема.
Ovl>поскольку я тупой до невозможности, то повторяю свой вопрос: Ovl>какие именно преимущества сводятся на нет при использовании спецификаторов dllexport/dllimport?
Твоя самокритика не безосновательна.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re[7]: Можно ли импортировать класс из DLL при explicit lin
Здравствуйте, Ovl, Вы писали:
Ovl>я например привык писать .def даже при __declspec(dllexport). просто привычка. смотрится приятней. кроме того тогда удобнее и явно библиотечку подгружать. Ovl>то бишь использование __declspec(dllexport) не мешает явно получать доступ к библиотеке, .DEF и dllexport могут существовать вместе — это не проблема.
Visual C++ Concepts: Adding Functionality
Importing and Exporting
You can import public symbols into an application or export functions from a DLL using two methods:
Use a module definition (.DEF) file when building the DLL.
Use the keywords __declspec(dllimport) or __declspec(dllexport) in a function definition in the main application.
Using a .DEF file
A module-definition (.DEF) file is a text file containing one or more module statements that describe various attributes of a DLL. If you do not use __declspec(dllimport) or __declspec(dllexport) to export a DLL's functions, the DLL requires a .DEF file.
You can use .DEF files to import into an application or to export from a DLL.
Using __declspec
The 32-bit edition of Visual C++ uses __declspec(dllimport) and __declspec(dllexport) to replace the __export keyword previously used in 16-bit versions of Visual C++.
You do not need to use __declspec(dllimport) for your code to compile correctly, but doing so allows the compiler to generate better code. The compiler is able to generate better code because it knows for sure whether a function exists in a DLL or not, so the compiler can produce code that skips a level of indirection that would normally be present in a function call that crossed a DLL boundary. However, you must use __declspec(dllimport) in order to import variables used in a DLL.
With the proper .DEF file EXPORTS section, __declspec(dllexport) is not required. __declspec(dllexport) was added to provide an easy way to export functions from an .EXE or .DLL without using a .DEF file.
Можно конечно кататься на велосипеде, отталкиваясь лыжными палками, только зачем?
Ovl>поскольку я тупой до невозможности, то повторяю свой вопрос: Ovl>какие именно преимущества сводятся на нет при использовании спецификаторов dllexport/dllimport?
Pros and Cons of Using .DEF Files
Exporting functions in a .DEF file gives you control over what the export ordinals are. When you add additional exported functions to your DLL, you can assign them higher ordinal values (higher than any other exported function). When you do this, applications using implicit linking do not have to relink with the new import library that contains the new functions. This is very important, for example, if you are designing a third-party DLL for use by many applications. You can continue to enhance your DLL by adding additional functionality while at the same time ensuring that existing applications will continue to work properly with the new DLL. The MFC DLLs are built using .DEF files.
Pros and Cons of Using __declspec(dllexport)
Using __declspec(dllexport) is convenient because you do not have to worry about maintaining a .DEF file and obtaining the decorated names of the exported functions. However, you do not have control over the export ordinals that the compiler generates. This method is suitable if, for example, you are designing a DLL for use with an application that you control; if you rebuild the DLL with new exports, you will also have to rebuild the application.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг