C ++: встроенные функции с dllimport / dllexport? - PullRequest
3 голосов
/ 16 января 2012

Я создаю DLL (скажем, CORE.DLL), у меня есть классы / функции, объявленные следующим образом:

#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 / dllimport?

Ответы [ 2 ]

8 голосов
/ 16 января 2012

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

Вы либо

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

Нет никакого смысла пытаться делать оба одновременно.

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

Редактировать Чтобы устранить любые недоразумения: можно экспортировать и импортировать встроенные функции, и на самом деле простое размещение dllexport / dllimport в объявлении должно просто работать.

4 голосов
/ 25 мая 2017

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

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...