Встроенный и dlimport/dllexport

Сейчас я анализирую какой-то старый код, который я не написал. В заголовках есть много объявлений вроде этого:

SVPDSDKDLLEXPORT inline C3vec mult(C3vec src, D3DXMATRIX &m);

SVPDSDKDLLEXPORT определяется как _declspec(dllexport), если он используется в SVPDSDK; как _declspec(dllimport), если он используется в любом проекте, который использует SVPDSDK.dll. Вставка здесь кажется мне очень странной, поскольку в заголовке нет определения, оно находится в файле.cpp, но компиляция и компоновка SVPDSDK и всех проектов, использующих соответствующую DLL, выполняются без каких-либо проблем. Я предполагаю, что это просто игнорируется и функция экспортируется так, как если бы она не была встроенной.

Я нашел это обсуждение: C++: встроенные функции с dllimport/dllexport?

Похоже, я должен был удалить "inline" из всех таких объявлений, не смешивая встраивание и экспорт / импорт. Но потом я нашел эту тему в MSDN: http://msdn.microsoft.com/en-us/library/xa0d9ste

Я не понимаю некоторые его части.

Вы можете определить как встроенную функцию с атрибутом dllexport. В этом случае функция всегда создается и экспортируется независимо от того, ссылается ли функция на какой-либо модуль в программе. Предполагается, что эта функция импортирована другой программой.

Во-первых, "функция всегда создается", что это значит? Я нашел только темы, посвященные реализации функций шаблонов в C++, никаких других примеров. Это связано только с шаблонами или нет?

Во-вторых, "функция всегда экспортируется". Я совсем не понимаю. Возможно ли, что функция с declspec(_dllexport) не экспортируется в некоторых случаях? В каких случаях?

Теперь об импорте:

Вы также можете определить как встроенную функцию, объявленную с атрибутом dllimport. В этом случае функция может быть расширена (с учетом спецификаций /Ob), но никогда не может быть реализована. В частности, если взят адрес встроенной импортированной функции, возвращается адрес функции, находящейся в DLL. Это поведение аналогично получению адреса не встроенной импортированной функции.

Опять же, я не понимаю, что означает инстанцирование в этом случае.

При написании этого вопроса и анализе темы из MSDN я пришел к выводу, что эта функция, которая экспортируется / импортируется и одновременно встроена, встроена только в сам проект (в моем случае SVPDSDK) и не является встроенной во всех импорт проектов. Это явно не заявлено в теме MSDN. Если я не импортирую его в какой-либо проект, который его использует, и у меня нет определения в его заголовочном файле, это будет обычная встроенная функция, поэтому я получу ошибку компоновки. Тогда мне кажется, что приемлемо смешивать встраивание и экспорт / импорт, хотя это противоречит ответу в обсуждении стека переполнения, упомянутому выше. Я прав?
И я до сих пор не понимаю всех этих слов о реализации встроенных функций.

Извините, что я объединил некоторые вопросы в одной теме, но я не знаю, как разделить их на отдельные, потому что они объединены одной проблемой и одинаковыми материалами. Тем не менее, я был бы признателен, если бы кто-нибудь мог прояснить этот вопрос для меня.

1 ответ

Решение

По факту, inline это своего рода подсказка для оптимизатора. Компилятор все еще может генерировать реальную функцию с телом, помещая аргументы в стек и т. Д. Это не нарушит никакой логики. Это определенно будет сделано, если ваша "встроенная" функция будет иметь более 10000 строк кода. У Microsoft даже есть специальные __forceinline ключевое слово. Угадай, почему это было введено.

The function is always instantiated and exported ...

Формулировка может быть не идеальной здесь. Инстанциация означает здесь, что тело и точка входа будут сгенерированы. Это не имеет ничего общего с созданием шаблона. Весь абзац означает, что __declspec важнее, чем inline,

За dllimport они в основном пишут, что dllimport предотвращает генерацию тела этой встроенной функции в текущем двоичном модуле, в то время как встроенное расширение все еще возможно.

Другие вопросы по тегам