Использование предварительно скомпилированных заголовков в проекте статической библиотеки - PullRequest
1 голос
/ 15 ноября 2010

Мне нужен совет о том, как настроить мой проект.Я собираю статическую библиотеку и хочу узнать, правильно ли я использую предварительно скомпилированные заголовки, прежде чем идти слишком далеко.

Пока что мой файл stdafx просто включает (для типов, таких как DWORD и т. Д..) и (для std :: string).

Я создал простую комбинацию cpp / header под названием TestFuncs.cpp / h

TestFuncs.cpp:

#include "stdafx.h"
using namespace std;
void MyFunc(DWORD a, string b) {
    // irrelevant
}

TestFuncs.h

#pragma once
void MyFunc(DWORD a, std::string b);

Этот код здесь компилируется правильно.Проблема, с которой я сталкиваюсь, заключается в том, что когда я хочу использовать эту статическую библиотеку в другом проекте, я обычно делаю #include "path_to_my_static_lib_project / TestFuncs.h"

Однако проблема с этим основана на TestFuncs.hи DWORD, и string будут в то время неизвестны, так как они являются типами, определенными из файла stdafx.h.

Одно решение, которое я придумал (я не знаю, правильно ли это делать) просто включает stdafx.h вверху TestFuncs.h после #pragma один раз.Теперь файл проекта работает с использованием предварительно скомпилированных заголовков или нет.

Это так и должно быть, или есть правильный способ сделать это?

Спасибо.

1 Ответ

5 голосов
/ 15 ноября 2010

Не #include "stdafx.h" в публичном заголовочном файле вашей библиотеки. Под открытым заголовочным файлом я подразумеваю заголовочный файл, который клиенты вашей библиотеки будут #include.

Вместо этого определите только абсолютный минимум и предпочтительно используйте в этом файле 100% переносимый код. Также избегайте использования STL, если ваша библиотека будет использоваться разными компиляторами или платформами.

Итак, предположим, у вас есть открытый заголовочный файл my_library.h, который реализован в gizmo.cpp. У вас будет следующее:

gizmo.cpp

#include "stdafx.h"
#include "my_library.h"

int GizmoTronic()
{ 
  // ...
  return 42;
}

Кроме того, не по теме, но используйте защиту от макросов, а не #pragma once, которая не является частью языка C ++ и поэтому поддерживается не всеми компиляторами. Это плохая привычка.

EDIT:

Что касается вопроса о том, что DWORD и string не определены, когда ваш заголовок #include -ed, у меня есть 3 предложения:

1) Используйте только переносимые типы данных. То есть типы данных, определенные стандартом. DWORD - изобретение от Microsoft (десятилетия назад). Это не часть языка, и это не переносимо. Вместо этого используйте unsigned long или что-то еще подходящее.

2) Не используйте string в открытом интерфейсе вашей библиотеки, если ваша библиотека будет использоваться кодом, скомпилированным с компилятором, отличным от вашего. Причина в том, что string полностью определен в заголовочных файлах, поэтому каждый компилятор потенциально имеет свою собственную реализацию. string одного компилятора может отличаться от другого.

3) Предполагая, что # 2 не применяется, не стесняйтесь #include любых необходимых заголовков из стандартной библиотеки в верхней части заголовка. Если вы используете string в общедоступном интерфейсе, #include <string> в заголовке. (Только, пожалуйста, не using namespace std). Ваш заголовок должен быть автономным.

EDIT2:

Вот как я бы объявил вашу функцию:

void MyFunc(unsigned long a, const char* b);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...