Как использовать класс в DLL? - PullRequest
19 голосов
/ 29 декабря 2010

Могу ли я поместить класс в DLL? Класс, который я написал, это:

    class SDLConsole
{
      public:
             SDLConsole();
             ~SDLConsole(){};
             void getInfo(int,int);
             void initConsole(char*, char*, SDL_Surface*, int, int, int);
             void sendMsg(char*,int, SDL_Surface*);
             void cls(SDL_Surface*);

      private:
              TTF_Font *font;
              SDL_Surface *consoleImg;
              int width, pos, height, line, size, ctLine;
              SDL_Surface* render(char*,int);

};

Я знаю, как загрузить DLL и использовать функцию внутри DLL, но как я могу поместить класс в DLL? Большое спасибо.

Ответы [ 4 ]

25 голосов
/ 29 декабря 2010

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

class ISDLConsole
{
  public:             
         virtual void getInfo(int,int) = 0;
         virtual void initConsole(char*, char*, SDL_Surface*, int, int, int) = 0;
         virtual void sendMsg(char*,int, SDL_Surface*) = 0;
         virtual void cls(SDL_Surface*) = 0;
 };

 class SDLConsole: public ISDLConsole
 {
    //rest of the code
 };

 __declspec(dllexport) ISDLConsole *Create()
 {
    return new SDLConsole();
 }

В противном случае, если вы связываете dll во время загрузки, просто используйте информацию, предоставленную icecrime: http://msdn.microsoft.com/en-us/library/a90k134d.aspx

13 голосов
/ 29 декабря 2010

Решение , предложенное bcsanches ,

 __declspec(dllexport) ISDLConsole *Create()
 {
    return new SDLConsole();
 }

Если вы собираетесь использовать этот подход в качестве предложенного от bcsanches , то убедитесь, что вы используете следующую функцию для delete вашего объекта,

 __declspec(dllexport) void Destroy(ISDLConsole *instance)
 {
       delete instance;
 }

Определите такие функции всегда в паре, поскольку гарантирует , что вы удаляете свои объекты из той же кучи / пула памяти / и т. Д., В которой они были созданы. Смотрите это пара функций

5 голосов
/ 29 декабря 2010

Вы можете, и вся необходимая информация находится на этой странице и этой странице :

#ifdef _EXPORTING
   #define CLASS_DECLSPEC __declspec(dllexport)
#else
   #define CLASS_DECLSPEC __declspec(dllimport)
#endif

class CLASS_DECLSPEC SDLConsole
{
    /* ... */
};

Осталось только определить символ препроцессора _EXPORTING при сборке DLL.

2 голосов
/ 29 декабря 2010

Если вы хотите представить данные в классе, приведенные выше решения не будут сокращать их. Вы должны добавить __declspec(dllexport) к самому классу в компиляции DLL и __declspec(dllimport) в модуле, который связан с DLL.

Обычный способ сделать это (мастера Microsoft создают такой код):

#ifdef EXPORT_API
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif

class MY_API MyClass {
   ...
};

Затем убедитесь, что в проекте DLL определено EXPORT_API, и убедитесь, что оно не определено в модуле, который ссылается на DLL.

Если вы создаете новый проект DLL в Visual C ++ с нуля и устанавливаете флажок «Экспортировать символы», с помощью этого метода будет создан некоторый пример кода.

...