2015-05-13 4 views
1

У меня есть класс, экспортированный в dll. И получил встроенные функции в этом классе экспортируемого:ошибка привязки встроенной функции redefinition

header.h

class MODULE_EXPORT A 
{ 
public: 
    int GetInt(){ return iSomeInt; } 
}; 

Когда я включить этот заголовочный файл в отдельном модуле. Я получил ошибку LNK2005, что означает: GetInt() уже определен.

Если я поместил определение функции в файл .cpp. Ошибка НЕТ.

GetInt является встроенной функцией, если я определяю ее таким образом в файле заголовка, правильно? так почему ошибка переустановки связи? Я использую компилятор vC++. (Visual Studio 2010).

EDIT:

#pragma once 

уже был добавлен в файл заголовка. Забыл упомянуть об этом.

+3

Вы не должны экспортировать встраиваемую функцию, должны ты ? –

+0

ну, это пункт. Воодушевление! @YvesDaoust –

+0

Если вы помечаете класс как экспортированный, каждый .cpp, который включает определение класса, генерирует копию метода. Две проблемы: компоновщик будет жаловаться, и функция может не быть встроена! Воздерживаться от экспорта метода. –

ответ

0

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

Однако функция уже определена в dll.

Решение будет размещать определение в файле cpp, как вы отметили, или использовать ключевое слово static, поэтому определение доступно только для единицы компиляции, в которой он определен, а не те, которые его включают.

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

+0

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

+0

gcc и msvcc автоматически встраивают простые функции, подобные этому, либо если они находятся в заголовке (встраивание компилятора), либо в cpp (компоновщик может встроить). Таким образом, явное размышление о внедрении для производительности кажется немного спорным IMO. – user1646196

+0

Будет ли MSVC встроить функцию из DLL во время выполнения? Ваше сообщение, по сути, говорит, что «вложение небольших/простых функций не является преимуществом». – Mat

0

Это классическая проблема начинающего C/C++: поскольку вы включаете свой .h в несколько мест, вы получаете несколько экземпляров одного и того же метода. Самый интуитивный и, следовательно, несколько правильный метод решения этого вопроса - это метод в файле .cpp. Во всяком случае, ваш компилятор, вероятно, включит его.

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

Затем используйте надлежащие включенные охранники (ищите #pragma once или #ifndef __FILE_NAME_H__ или аналогичные в начале файла .h).

Тогда определение вашего метода является его декларацией и должно заканчиваться ;.

Кроме того, обратите внимание, что ваш метод не изменяет свой класс, так что вы должны использовать ключевое слово const:

#ifndef __Header_h__ 
#define __Header_h__ 
class MODULE_EXPORT A { 
    private: 
    int internalint; 
    public: 
    int getInt() const; 
}; 
#endif 

.cpp

int A::getInt() const { 
    return internalint; 
} 
+0

Я получил множество функций, таких как GetInt(), определенных как inline в классе A. Но не все из них вызывают ошибку привязки redefiniton. Означает ли это, что компилятор не рассматривал все из них как вложенные? @Marcus –

+2

Это неправильно. Функция автоматически встроена, потому что она определена внутри определения класса. Это не «классическая проблема начинающего C/C++» (что такое «C/C++»?); это более сложная проблема, связанная с экспортом DLL. И как вы ожидаете, что _compiler_ будет выполнять встроенные вызовы функций через TU? Через границы DLL? lol –

+0

@LightnessRacesinOrbit, вы правы в этом. Я не должен ожидать от компилятора встроенной функции через границы dll, что невозможно. Но не вся встроенная функция сообщает, что связывает ошибку, как это объяснить? теоретически? –

Смежные вопросы