bgrimstad / splinter

Library for multivariate function approximation with splines (B-spline, P-spline, and more) with interfaces to C++, C, Python and MATLAB
Mozilla Public License 2.0
418 stars 115 forks source link

Protected constructor BSpline() results in error C2248 - cannot access protected member #131

Closed dknippel closed 2 years ago

dknippel commented 2 years ago

When trying to compile my library that consumes bspline.h I receive error C2248 from VS2019

'SPLINTER::BSpline::BSpline': cannot access protected member declared in class 'SPLINTER::BSpline' from 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xmemory 714'

This appears to be a result of the empty constructor BSpline() located on line 129 in blspline.h. I noticed in your commit history that said constructor used to be public rather than protected.

If I move said constructor up a few lines so that it is marked as public then said error is replaced with a different error that complains about an 'unresolved external' which I'm guessing is due to a missing empty constructor implementation in bspline.cpp ?

Is there a way to fix this?

gablank commented 2 years ago

Hi @dknippel.

It's been quite a while since I worked on the library, but I seem to remember that the way to construct a BSpline is through the BSplineBuilder, and not by instantiating the BSpline directly.

Have you tried that?

dknippel commented 2 years ago

Hi @gablank, thank you for the superfast reply! ;-)

I've confirmed that my code is indeed using the BSplineBuilder to build an array of BSpline objects like so:

BSplines[k] = SPLINTER::BSpline::Builder(splineTable)
                        .degree(5)
                        .smoothing(SPLINTER::BSpline::Smoothing::PSPLINE)
                        .knotSpacing(SPLINTER::BSpline::KnotSpacing::EQUIDISTANT)
                        .build();

However, I think the error that the VS2019 compiler was giving was when it was trying to compile the Splinter headers, and not my library (PISCES.lib) that is wanting to consume it.

Also, when I move said BSline() constructor up a few lines and thus declared under public:, the VS2019 compiler is able to successfully compile the splinter headers and thus, my PISCES.lib. Unfortunately, another C++/CLI DLL that consumes PISCES.lib then barfs up the following error:

Error LNK2019 unresolved external symbol "public: __cdecl SPLINTER::BSpline::BSpline(void)" (??0BSpline@SPLINTER@@QEAA@XZ) referenced in function "public: static void __cdecl std::_Default_allocator_traits<class std::allocator<class SPLINTER::BSpline> >::construct<class SPLINTER::BSpline>(class std::allocator<class SPLINTER::BSpline> &,class SPLINTER::BSpline * const)" (??$construct@VBSpline@SPLINTER@@$$V@?$_Default_allocator_traits@V?$allocator@VBSpline@SPLINTER@@@std@@@std@@SAXAEAV?$allocator@VBSpline@SPLINTER@@@1@QEAVBSpline@SPLINTER@@@Z) Biplane.CLI D:\dev\Biplane\Biplane.CLI\PISCES.lib(FlatfieldCorrection.obj) 1

Any thoughts on why this unresolved external is happening? I saw the SPLINTER::BSpline::BSpline(void) and thought maybe it was due to an empty constructor not being defined??? Admittedly, I'm kind of lost.

gablank commented 2 years ago

Did you recompile SPLINTER after that change? If not, I'd wager that doing so would fix the issue. Seems like MSVC (which it seems you are using) uses the access specifier (public, private, protected) in the name mangling (see https://stackoverflow.com/questions/3365247/which-c-compilers-use-the-access-specifier-in-name-mangling), so changing it in the header without recompiling the library will probably make the linker look for the wrong symbol in the DLL.

Edit: I tried "demangling" the mangled function name, and it clearly has "public" in it: image I also just noticed that the error message also includes it (unresolved external symbol "public: __cdecl SPLINTER::BSpline::BSpline(void)")

gablank commented 2 years ago

Also, if I remember correctly, we never really tested the library that much with MSVC, but we used MinGW. You might have better luck trying that out, if it's an option for you.

dknippel commented 2 years ago

Wooohooo! You were right, that was it!!! Excellent, thank you so much :-D

dknippel commented 2 years ago

Hi Anders, @gablank thanks again for your help in resolving this issue.

I was curious, the artifacts deposited into the lib/ folder are as follows:

I only seem to need the last one, splinter-static-3-0.lib However, what are the 5 files for or perhaps what is the reason for the naming conventions?

gablank commented 2 years ago

Hi,

Are you using MinGW? I'd guess the .dll files uses Microsoft's calling convention and is binary compatible with code MSVC generates, while the others use the GCC/MinGW calling convention. One for dynamic linking and one for static linking each, but not sure why there seem to be an odd number of them.

On Wed, Mar 2, 2022, 19:38 Dennis M. Knippel @.***> wrote:

Hi Anders, thanks again for your help in resolving this issue.

I was curious, the artifacts deposited into the lib/ folder are as follows:

  • libsplinter-3-0.dll
  • libsplinter-3-0.dll.a
  • libsplinter-static-3-0.a
  • splinter-3-0.lib
  • splinter-static-3-0.lib

I only seem to need the last one, splinter-static-3-0.lib However, what are the 5 files for or perhaps what is the reason for the naming conventions?

— Reply to this email directly, view it on GitHub https://github.com/bgrimstad/splinter/issues/131#issuecomment-1057256692, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAK2UETKLLVMB2VNJCIIEYTU56YRLANCNFSM5PFJKIRA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

dknippel commented 2 years ago

I'm using MSVC's cmake.exe that comes with VS2019.

Ah, so this may be a MSVC cmake.exe issue with regard to what artifacts it spits out. OK, that helps. Thanks again! :-)