Skip to content

Commit 825bb36

Browse files
committed
BUG: Fix linking by making LBFGS2Optimizerv4 a template
Having LGBFGS2 being a compiled class in the Optimizerv4 library created linking errors from duplicate symbols on Windows with shared libraries in certain situations. The cause is that the parent classes of LBGFS2 were templated, and their link specifcation is not compatibile for them being in a shared library. The implemented solution was to make the LBFGS2 Optimizer a template class like its parents so that its symbols will not be in a shared library.
1 parent da7f448 commit 825bb36

File tree

4 files changed

+638
-547
lines changed

4 files changed

+638
-547
lines changed

Modules/Numerics/Optimizersv4/include/itkLBFGS2Optimizerv4.h

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
namespace itk
2626
{
2727
/*** \class LBFGS2Optimizerv4Enums
28-
* \brief Scoped Enum classes for LBFGS2Optimizerv4 class
28+
* \brief Scoped Enum classes for LBFGS2Optimizerv4Template class
2929
* \ingroup ITKOptimizersv4
3030
*/
3131
class LBFGS2Optimizerv4Enums
@@ -82,7 +82,7 @@ extern ITKOptimizersv4_EXPORT std::ostream &
8282
operator<<(std::ostream & out, LBFGS2Optimizerv4Enums::LineSearchMethod value);
8383

8484
/**
85-
*\class LBFGS2Optimizerv4
85+
*\class LBFGS2Optimizerv4Template
8686
* \brief Wrap of the libLBFGS[1] algorithm for use in ITKv4 registration framework.
8787
* LibLBFGS is a translation of LBFGS code by Nocedal [2] and adds the orthantwise
8888
* limited-memmory Quais-Newton method [3] for optimization with L1-norm on the
@@ -153,11 +153,13 @@ extern ITKOptimizersv4_EXPORT std::ostream &
153153
*
154154
* \ingroup ITKOptimizersv4
155155
*/
156-
class ITKOptimizersv4_EXPORT LBFGS2Optimizerv4 : public GradientDescentOptimizerv4Template<double>
156+
template <typename TInternalComputationValueType>
157+
class ITK_TEMPLATE_EXPORT LBFGS2Optimizerv4Template
158+
: public GradientDescentOptimizerv4Template<TInternalComputationValueType>
157159
{
158160

159161
public:
160-
ITK_DISALLOW_COPY_AND_MOVE(LBFGS2Optimizerv4);
162+
ITK_DISALLOW_COPY_AND_MOVE(LBFGS2Optimizerv4Template);
161163

162164
using LineSearchMethodEnum = LBFGS2Optimizerv4Enums::LineSearchMethod;
163165
#if !defined(ITK_LEGACY_REMOVE)
@@ -181,14 +183,14 @@ class ITKOptimizersv4_EXPORT LBFGS2Optimizerv4 : public GradientDescentOptimizer
181183
using PrecisionType = double;
182184

183185
/** Standard "Self" type alias. */
184-
using Self = LBFGS2Optimizerv4;
185-
using Superclass = GradientDescentOptimizerv4Template<double>;
186+
using Self = LBFGS2Optimizerv4Template;
187+
using Superclass = GradientDescentOptimizerv4Template<TInternalComputationValueType>;
186188
using Pointer = SmartPointer<Self>;
187189
using ConstPointer = SmartPointer<const Self>;
188190

189-
using MetricType = Superclass::MetricType;
190-
using ParametersType = Superclass::ParametersType;
191-
using ScalesType = Superclass::ScalesType;
191+
using MetricType = typename Superclass::MetricType;
192+
using ParametersType = typename Superclass::ParametersType;
193+
using ScalesType = typename Superclass::ScalesType;
192194

193195
/** Stop condition return string type */
194196
using typename Superclass::StopConditionReturnStringType;
@@ -197,7 +199,7 @@ class ITKOptimizersv4_EXPORT LBFGS2Optimizerv4 : public GradientDescentOptimizer
197199
itkNewMacro(Self);
198200

199201
/** Run-time type information (and related methods). */
200-
itkTypeMacro(LBFGS2Optimizerv4, GradientDescentOptimizerv4Template);
202+
itkTypeMacro(LBFGS2Optimizerv4Template, GradientDescentOptimizerv4Template);
201203

202204
/** Start optimization with an initial value. */
203205
void
@@ -457,8 +459,8 @@ class ITKOptimizersv4_EXPORT LBFGS2Optimizerv4 : public GradientDescentOptimizer
457459
itkBooleanMacro(EstimateScalesAtEachIteration);
458460

459461
protected:
460-
LBFGS2Optimizerv4();
461-
~LBFGS2Optimizerv4() override;
462+
LBFGS2Optimizerv4Template();
463+
~LBFGS2Optimizerv4Template() override;
462464
void
463465
PrintSelf(std::ostream & os, Indent indent) const override;
464466

@@ -534,8 +536,18 @@ class ITKOptimizersv4_EXPORT LBFGS2Optimizerv4 : public GradientDescentOptimizer
534536
void
535537
AdvanceOneStep() override
536538
{
537-
itkWarningMacro("LBFGS2Optimizerv4 does not implemenetd single step advance");
539+
itkWarningMacro("LBFGS2Optimizerv4Template does not implemenetd single step advance");
538540
};
539541
};
542+
543+
544+
/** This helps to meet backward compatibility */
545+
using LBFGS2Optimizerv4 = LBFGS2Optimizerv4Template<double>;
546+
540547
} // end namespace itk
548+
549+
#ifndef ITK_MANUAL_INSTANTIATION
550+
# include "itkLBFGS2Optimizerv4.hxx"
551+
#endif
552+
541553
#endif

0 commit comments

Comments
 (0)