C ++: inline functions with dllimport / dllexport?

I am creating a DLL (say CORE.DLL), I have classes / functions declared as follows:

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

I have defined many built-in functions with the dllexport macro,

 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; } 

but when I use this DLL (import), compile another DLL (let's say PluginA.DLL), it gives the following compilation errors:

 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&)' 

Any tips on using built-in functions with dllexport / dllimport?

+3
source share
2 answers

Inline and dllexport / dllimport do not mix.

You either

  • embed your functions and compile them separately for each source file that uses them; or
  • store them in the library, that is, compile them only once (export) and link the rest of the program with this single compiled version (import them).

There is little point in trying to do both at the same time.

Remove either from inline or RINZO_LIB from each function definition that has both, and you should be fine.

Change To resolve any misunderstandings: you can export and import built-in functions, and actually just placing dllexport / dllimport in an ad should just work.

+9
source

I would like to provide additional information, since this is a very complex problem, and there is good information about incorrect information that moves around the line with export / import.

First: built-in functions can be used with dllimport / dllexport without any problems. The point is perfectly reasonable: you provide a built-in definition that can be used inside your DLL or externally by client code (which can embed it), but you can still access it as if it were a standard exported function. In other words, you can still get a pointer to the implementation of a function that is in the DLL if you need it. Examples of use include, for example, accessing a function through FFI, the ability to access memory allocation / free procedures that must be built into modules, but they need to use a DLL for memory that crosses the DLL boundary, etc.

Please see https://blogs.msdn.microsoft.com/oldnewthing/20140109-00/?p=2123 for a thorough processing and clarification of what it means to be built-in and exported / imported at the same time.

Further, in your particular case, I do not see anything wrong with what you are trying to do. You want to provide fast, built-in vector math for yourself and your clients, while still having access to this function, as if it were a standard export. If this last bit is not true (i.e. you donโ€™t ever need to explicitly indicate the implementation of the DLL function of this function), then the comments / answer is correct: delete the export / import and make it part of .hpp. Use import / export + built-in only when you know that you still need access to the exported DLL version of the function . Again, this is a very reasonable thing, but usually it is not as required - so make sure that you really require it.

All that is said is that your DLL does not export characters.

Double check that you defined RINZOCORE_SHARED when creating the library. Check the DLL characters and see if these functions have been exported (if not, and you are sure that you have defined RINZOCORE_SHARED , then I am really dead end).

Make sure you include a heading that has function definitions wherever you call it. Make sure that RINZOCORE_SHARED NOT defined in your plugin assembly. It looks like your plugin is trying to find an exported version of the functions, which apparently implies that it does not have definitions for these built-in functions.

I usually use this only with C-linkage functions, so to be honest, I'm not entirely sure that everything can go wrong with C ++ ABI.

+2
source

All Articles