2012-01-16 4 views
3

я создаю DLL (например Core.dll), у меня есть классы/функции объявлены следующим образом:C++: встроенные функции с dllimport/dllexport?

#ifdef RINZOCORE_SHARED 
#define RINZO_LIB __declspec(dllexport) 
#else 
#define RINZO_LIB __declspec(dllimport) 
#endif 

я определил множество встроенных функций с "dllexport" макро,

class RINZO_LIB CVector 
{ 

public: 
    CVector();//!< default constructor 
    .. 
    real& x();//!< accessor for the x component (can be used as l-value too) 
    real& y();//!< accessor for the y component (can be used as l-value too) 
    real& z();//!< accessor for the z component (can be used as l-value too) 
    CVector& operator=(const CVector& other);//!< the assignment 
    CVector& operator+=(const CVector& other);//!< the sum & assign 
    CVector& operator-=(const CVector& other);//!< the subtract & assign 
    CVector& operator*=(const real& fact);//!< the short multiply by a scalar factor & assign 
    CVector& operator/=(const real& fact);//!< the short divide by a scalar factor & assign 
.. 
} 

RINZO_LIB inline CVector& CVector::operator=(const CVector& other) 
{ 
    //check for 'a=a' case 
    if (this==&other) return *this; 
    vec[0]=other.vec[0]; 
    vec[1]=other.vec[1]; 
    vec[2]=other.vec[2]; 
    return *this; 
} 

RINZO_LIB inline CVector& CVector::operator+=(const CVector& other) 
{ 
    vec[0]+=other.vec[0]; 
    vec[1]+=other.vec[1]; 
    vec[2]+=other.vec[2]; 
    return *this; 
} 

RINZO_LIB inline CVector& CVector::operator-=(const CVector& other) 
{ 
    vec[0]-=other.vec[0]; 
    vec[1]-=other.vec[1]; 
    vec[2]-=other.vec[2]; 
    return *this; 
} 

RINZO_LIB inline CVector& CVector::operator*=(const real& fact) 
{ 
    vec[0]*=fact; 
    vec[1]*=fact; 
    vec[2]*=fact; 
    return *this; 
} 

RINZO_LIB inline CVector& CVector::operator/=(const real& fact) 
{ 
    assert(fabs(fact) >= epsilon); 
    vec[0]/=fact; 
    vec[1]/=fact; 
    vec[2]/=fact; 
    return *this; 
} 

но когда Я использую эти DLL (импорт) компилировать другие DLL (скажет PluginA.DLL) она дает следующей ошибки компиляции:

Info: resolving std::cout by linking to __imp___ZSt4cout (auto-import) 
CMakeFiles\ContourViewer.dir/objects.a(RzStateDoAnimation.cpp.obj):C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/contourviewer/statemachine/RzStateDoAnimation.cpp:79: undefined reference to `operator!=(quaternion const&, quaternion const&)' 
Info: resolving vtable for __cxxabiv1::__vmi_class_type_info by linking to __imp___ZTVN10__cxxabiv121__vmi_class_type_infoE (auto-import) 
CMakeFiles\ContourViewer.dir/objects.a(RzStateDoAnimation.cpp.obj):C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/contourviewer/statemachine/RzStateDoAnimation.cpp:146: undefined reference to `operator==(quaternion const&, quaternion const&)' 
CMakeFiles\ContourViewer.dir/objects.a(BallController.cpp.obj):C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/contourviewer/trackball/BallController.cpp:159: undefined reference to `operator*(CVector const&, CVector const&)' 
CMakeFiles\ContourViewer.dir/objects.a(BallController.cpp.obj):C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/contourviewer/trackball/BallController.cpp:165: undefined reference to `operator^(CVector const&, CVector const&)' 
CMakeFiles\ContourViewer.dir/objects.a(BallController.cpp.obj):C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/contourviewer/trackball/BallController.cpp:168: undefined reference to `operator-(CVector const&, CVector const&)' 
CMakeFiles\ContourViewer.dir/objects.a(BallController.cpp.obj):C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/contourviewer/trackball/BallController.cpp:292: undefined reference to `operator*(CVector const&, CVector const&)' 
CMakeFiles\ContourViewer.dir/objects.a(BallController.cpp.obj):C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/contourviewer/trackball/BallController.cpp:292: undefined reference to `operator*(CVector const&, float const&)' 
CMakeFiles\ContourViewer.dir/objects.a(BallController.cpp.obj):C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/contourviewer/trackball/BallController.cpp:292: undefined reference to `operator-(CVector const&, CVector const&)' 

Любым советы о том, как использовать встроенные функции с dllexport/dllimpo rt?

+0

Что вы пытаетесь достичь? Что не так с очевидным решением - удалите 'inline'? –

+0

@DavidSchwartz на самом деле это часть кода, у меня много классов и множество встроенных функций. –

+0

@AshikaUmangaUmagiliya Исправьте меня, если я ошибаюсь, но функции 'inline' не существуют как отдельный фрагмент кода. Фактически, вы даже не можете определить их за пределами файла заголовка - они должны совпадать с объявлением класса и быть включены в каждый скомпилированный модуль, в котором они используются. Поэтому для вашей компиляции 'PluginA.cpp' вам необходимо предоставить« Core ». hpp' с объявлением класса, которое ДОЛЖНО включать определения всех 'inline' функций ANYWAY. – lapk

ответ

9

Inline и dllexport/dllimport не смешиваются.

Вы либо

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

Существует мало смысла в попытке сделать оба в одно и то же время.

Из любого определения функции удалите либо inline, либо RINZO_LIB, и вы должны быть в порядке.

Редактировать Для устранения каких-либо недоразумений: он является можно экспортировать и импортировать встроенные функции, а на самом деле просто помещая dllexport/DllImport на декларации должны просто работать.

+1

Они делают, и нет причин, почему то, что он делает, не может быть сделано. В его частном случае что-то другое вызывает проблему. См. Https://blogs.msdn.microsoft.com/oldnewthing/20140109-00/?p=2123 для подробного обсуждения встроенного экспорта и импорта. –

+0

@ JoshParnell Я не сказал, что это невозможно, я сказал, что это не имеет никакого смысла. Меня не волнует способ фактического экспорта/импорта встроенной функции, пока не будет веской причины использовать эту функцию, которую я просто не вижу здесь (или даже где-то еще). Отсюда практический совет: не делайте этого. –

+0

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

2

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

Первый: встроенные функции могут использоваться с dllimport/dllexport без проблем. Смысл совершенно разумный: вы предоставляете встроенное определение, которое может быть использовано внутренне в вашей DLL или внешне клиентским кодом (которое может встроить его), но все равно можно получить доступ, как если бы это была стандартная экспортированная функция. Другими словами, вы все равно можете получить указатель на реализацию функции, которая находится в в DLL, если вам это нужно. К примерам использования относятся, например, доступ к функции через FFI, возможность доступа к распределению памяти/бесплатные процедуры, которые должны быть встроены в модули, но им необходимо использовать имбук DLL для памяти, которая пересекает границу DLL и т. Д.

Пожалуйста, см. https://blogs.msdn.microsoft.com/oldnewthing/20140109-00/?p=2123 для тщательной обработки и уточнения того, что означает быть встроенным и экспортированным/импортированным одновременно.

Далее, в вашем конкретном случае, я не вижу ничего плохого в том, что вы пытаетесь сделать. Вы хотите обеспечить быструю, встроенную векторную математику для себя и клиентов, , сохраняя возможность доступа к этой функции, как если бы это был стандартный экспорт. Если этот последний бит недействителен (т. Е. Вам явно не нужен указатель на реализацию этой функции DLL), то комментарии/ответ верны: удалите экспорт/импорт и сделайте его частью. HPP.Используйте импорт/экспорт + inline только тогда, когда вы знаете, что вам все равно потребуется доступ к экспортированной версии DLL функции. Опять же, это вполне разумная вещь, однако, это не обычно что нужно - так что убедитесь, что вы действительно этого требуете.

Все, что сказано, похоже, что ваша DLL не экспортирует символы.

Двойная проверка, чтобы убедиться, что вы определяете RINZOCORE_SHARED при создании библиотеки. Проверьте символы DLL и посмотрите, были ли эти функции экспортированы (если нет, и вы уверены, что вы определили RINZOCORE_SHARED, то я действительно сильно тупик).

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

Обычно я использую это только с функциями C-linkage, поэтому я честно не совсем уверен, что все может пойти не так, как с C++ ABI.

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