Вопрос о соглашениях об именах в c ++ - PullRequest
1 голос
/ 21 августа 2011

Я пытаюсь создать слой абстракции для таких платформ, как win32, mac os, linux, iOs и т. Д. Я хочу, чтобы это было динамически связано.На платформах, которые не поддерживают это, это не должно быть проблемой, поскольку из того, что я видел, все, что может быть скомпилировано как динамическая библиотека, также может быть скомпилировано как статическая с минимальным воздействием на код.

Теперь, чтобы добраться до сути этого:

Я создал интерфейс с именем IThread и класс с именем CThread.Я использую функцию с именем CreateThread, которая определена с extern "C", чтобы иметь возможность экспортировать ее и вызывать вне библиотеки.Проблема здесь в том, что в win32, например, уже есть функция с именем CreateThread, и поэтому я получаю ошибку компоновщика.Я понимаю ошибку и почему она появляется, но я не уверена, что есть хороший способ избежать этого.Мне не очень нравится использовать странные имена, поскольку qt использует, например, CreateQtThread.
Другая идея, которую я имею, заключается в том, чтобы создать диспетчер / фабрику потоков, которая создает экземпляры CThread, но я не уверен, что это будет хорошей идеей.

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

Большое спасибо

Ответы [ 5 ]

5 голосов
/ 21 августа 2011

На мой взгляд, вы решили использовать extern "C", потому что он разрешает доступ с других языков, компиляторов и т.д.из вашей библиотеки, если хотите, из пространства имен бедного человека.

Это компромисс, который вы должны сделать, если хотите использовать extern "C".

5 голосов
/ 21 августа 2011

Ну, я не знаю, понравится ли вам это, поскольку я знаю, что разработчики C, с которыми я работал, сочли это неэстетичным. Но это очень просто и предотвращает подобные столкновения. (Более или менее упомянутый в этом ответе с комментарием "its_lib_prefix_function".)

Итак, всякий раз, когда я использовал код на C, я обычно «пространством имен» использовал свои функции, используя подчеркивание. Итак, допустим, ваше пространство имен равно MegaAbstraction, тогда что-то вроде CreateThread становится MegaAbstraction_CreateThread. Очень просто. И никаких коллизий, если только у кого-то еще нет пространства имен MegaAbstraction, в этом случае я рекомендую найти пространство имен, которое вряд ли будет использоваться кем-то еще. ;)

5 голосов
/ 21 августа 2011

Я использую функцию с именем CreateThread, которая определена с помощью extern "C", чтобы иметь возможность экспортировать ее и вызывать за пределами библиотеки.

Это плохо. Я не могу говорить о других платформах, но в Windows совершенно нормально экспортировать функции C ++. Они просто изуродованы, и вы получаете некоторую проверку вменяемости на случай, если кто-то изменит декларацию. Фактически, это единственный правильный способ экспортировать функцию, которая равна C ++. Если вы объявите его как extern «C», вы не получите ни пространства имен, ни перегрузки, и у того, кто компилирует с /EHsc, будут проблемы, если из вашей функции выйдет исключение.

Предпочтительное решение: не объявляйте их как внешние "C" и помещайте их в пространство имен.

Единственное другое решение: ну, угадайте, почему все эти библиотеки C ставят перед своими функциями префикс their_lib_prefix_function ...

1 голос
/ 22 августа 2011

Использует ли ваш CreateThread соглашение о вызовах stdcall (он же WINAPI)? Если вы используете соглашение о вызовах cdecl, оно должно экспортировать имя функции как _CreateThread и избегать конфликта связей с функцией Win32 CreateThread.

extern "C" _declspec(export) int _cdecl CreateThread(...
0 голосов
/ 28 августа 2011

В Qt нет функции "CreateQtThread", даже чего-то подобного. Есть класс QThread, и у него есть конструкторы. При необходимости вы можете поместить все в пространство имен.

...