[Insight-users] Re: Native ITK in Managed C++

Dan Mueller dan.muel at gmail.com
Mon Sep 17 17:45:52 EDT 2007


On 18/09/2007, Young-Seok Kim <ykim5forward at yahoo.com> wrote:
> Hi Dan,
>
> Thanks for kind reply.
> First of all, this part is my 'big' question actually.
>
> >> Let me also say, if you are using C++/CLI (Managed C++) then I would
> recommend calling the native ITK classes directly (ie. not to use
> ManagedITK). This approach allows you direct access to the ITK
> modules, rather than going through an intermediate wrapper
> (ManagedITK).
>
> I have Managed C++/CLI code for my application right now (don't want MFC).
> Can I 'directly' access to native ITK libraries in the project? (Not via
> wrapper classes).

Yes, you can build a C++/CLI application which uses the native ITK
modules. ManagedITK does exactly that (except it exposes an API
similar to ITK eg. the class itkImage has the Allocate(),
DisconnectPipeline(), FillBuffer() methods, etc.) You can do exactly
the same, except your API can be whatever you want eg. the public
class called MyItkCode has the methods DoStuff1() and DoStuff2().

> This was the exactly same situation with my old native libraries - I had to
> include all the source code in the project, which is nasty. Also, I had to
> remove all the C codes, that is for jpeg file manipulation.
> If possible, I actually prefer to stick on native ITK, since (1) Managed ITK
> doesn't support all features of ITK, and (2) I want to use original manual
> and example.
>
> Could you explain how to use native ITK in Managed C++/CLI?
> I have spent lots of time with .lib files, but didn't work.

Making it work is not exactly "easy". The reason being: CMake does not
support C++/CLI projects (and we shouldn't really expect it to, seeing
that C++/CLI is a Windows language only). You have two options: use
CMake or go it alone.

-- Using CMake --
The ManagedITK project uses CMake: it creates a C++ SHARED library
with C++/CLI code files (see Source/CMakeLists.txt for an example).
However, after configuring the project with CMake, the project file
(vcproj) must be "mangled" to support managed compilation. The
FinishCMake.bat that the ManagedITK project generates automates this
mangling. To each project you must edit the vcproj file (or manually
set the properties using Visual Studio):
  1. Add ManagedExtensions="1" (this can be done manually by browsing
to "Configuration Properties > General" and setting "Common Language
Runtime Support" to /clr )
  2. Make all ExceptionHandling="2" (this can be done manually by
browsing to "Configuration Properties > C/C++ > Code Generation" and
setting the "Enable C++ Exceptions" field to "Yes With SEH Exceptions
(/EHa)"
  3. Ensure that BasicRuntimeChecks="0" (this can be done manually by
browsing to "Configuration Properties > C/C++ > Code Generation"  and
setting "BasicRuntimeChecks" to "Default".

If you have used CMake correctly, it will have automatically
configured the "Additional Include Directories", "Additional Library
Directories" and "Additional Dependencies" project properties.

-- Going it alone --
If you go it alone (do not use CMake to configure your project) you
must create a C++/CLI CLR project and set the "Additional Include
Directories", "Additional Library Directories" and "Additional
Dependencies" properties manually to the correct values (create a
native ITK project with CMake and see what values are used).

I have created a (very) simple CLR Console application which uses
native ITK, compiles, and runs without problem:

#include "stdafx.h"
#include "itkImage.h"

using namespace System;

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Allocating image...");
    typedef itk::Image<float> ImageType;
    ImageType::Pointer image = ImageType::New();
    ImageType::SizeType  size;
    size[0]  = 200;  // size along X
    size[1]  = 200;  // size along Y
    size[2]  = 200;  // size along Z
    ImageType::RegionType region;
    region.SetSize( size );
    image->SetRegions( region );
    image->Allocate();
}

On my machine (it WILL be different on yours!) the properties were as follows:

AdditionalIncludeDirectories="C:\InsightToolkit-3.2.0-CVS\Utilities\vxl\vcl;C:\InsightToolkit-3.2.0-CVS\Utilities\vxl\core\vnl;C:\InsightToolkit-3.2.0-CVS\Utilities\vxl\core;C:\InsightToolkit-3.2.0-CVS\Utilities\vxl;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK\Build\Source\Modules;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK\Build\Source;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK\Build\Source\Modules\Calculators;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK\Source\Modules\Calculators;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK\Build;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK\Source\Common\FastMorphology;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK\Source\Common;C:\InsightToolkit-3.2.0-CVS\Wrapping\ManagedITK\Source\Modules;C:\InsightToolkit-3.2.0-CVS\Code\Review;C:\InsightToolkit-3.2.0-CVS\Utilities\gdcm\src;C:\InsightToolkit-3.2.0-CVS\Build\Utilities\gdcm;C:\InsightToolkit-3.2.0-CVS\Build\Utilities\vxl\core;C:\InsightToolkit-3.2.0-CVS\Build\Utilities\vxl\vcl;C:\InsightToolkit-3.2.0-CVS\Build\Code\Common;C:\InsightToolkit-3.2.0-CVS\Utilities;C:\InsightToolkit-3.2.0-CVS\Build\Utilities;C:\InsightToolkit-3.2.0-CVS\Utilities\itkExtHdrs;C:\InsightToolkit-3.2.0-CVS\Utilities\nifti\znzlib;C:\InsightToolkit-3.2.0-CVS\Utilities\nifti\niftilib;C:\InsightToolkit-3.2.0-CVS\Utilities\expat;C:\InsightToolkit-3.2.0-CVS\Build\Utilities\expat;C:\InsightToolkit-3.2.0-CVS\Build\Utilities\DICOMParser;C:\InsightToolkit-3.2.0-CVS\Utilities\DICOMParser;C:\InsightToolkit-3.2.0-CVS\Utilities\NrrdIO;C:\InsightToolkit-3.2.0-CVS\Utilities\MetaIO;C:\InsightToolkit-3.2.0-CVS\Code\SpatialObject;C:\InsightToolkit-3.2.0-CVS\Code\Numerics\NeuralNetworks;C:\InsightToolkit-3.2.0-CVS\Code\Numerics\Statistics;C:\InsightToolkit-3.2.0-CVS\Code\Numerics\FEM;C:\InsightToolkit-3.2.0-CVS\Code\IO;C:\InsightToolkit-3.2.0-CVS\Code\Numerics;C:\InsightToolkit-3.2.0-CVS\Code\Common;C:\InsightToolkit-3.2.0-CVS\Code\BasicFilters;C:\InsightToolkit-3.2.0-CVS\Code\Algorithms;C:\InsightToolkit-3.2.0-CVS\Build;"

AdditionalLibraryDirectories="c:\InsightToolkit-3.2.0-CVS\Build\bin\$(OutDir);c:\InsightToolkit-3.2.0-CVS\Build\bin\Release;c:\InsightToolkit-3.2.0-CVS\Build\bin;"

AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
ITKIO.lib ITKCommon.lib ITKNumerics.lib ITKBasicFilters.lib
ITKStatistics.lib itkvnl.lib itkvnl_algo.lib itkv3p_netlib.lib
ITKNrrdIO.lib itkgdcm.lib itkjpeg12.lib itkjpeg16.lib itkopenjpeg.lib
snmpapi.lib itkpng.lib itktiff.lib itkjpeg8.lib ITKSpatialObject.lib
ITKMetaIO.lib wsock32.lib ITKDICOMParser.lib ITKEXPAT.lib
ITKniftiio.lib ITKznz.lib itkzlib.lib itkvnl_inst.lib itksys.lib
itkvcl.lib $(NOINHERIT)"

Best of luck.

Cheers, Dan

> Best regards,
> Young.
>
> Dan Mueller <dan.muel at gmail.com> wrote:
> Hi Young,
>
> Thanks for your question regarding ManagedITK. In the future, it is
> probably best to email your questions to the Insight Users mailing
> list: that way other people can search for the answer if they have
> similar questions.
>
> > I want to use Managed ITK Segmentation functions with my own application
> of Managed C++ (Window Forms, CLR, MSVC 8.0). But I have problems calling
> ITK object directly in Cpp files. Whenever I create an object, the compiler
> complaints "error C3767: candidate functions(s) not accessible".
>
> The error you are getting could be caused by a number of different
> things. To work it out it would be helpful if you could email me the
> answers to these questions:
> 1. Are you using the pre-compiled or your own compiled version of
> ManagedITK?
> 2. Are you using Visual Studio SP1? The pre-compiled assemblies I
> have uploaded to the Insight Journal were compiled with SP1 and
> therefore any application you create to use them must use SP1. I can
> provide non-SP1 assemblies if you want, or you can install SP1 (which
> takes a long time ~ 2 hours) or you could re-compile ManagedITK on
> your computer without SP1 (which can take longer ~ 2 - 4 hours).
> 3. Are you sure the project you are working on is Managed C++? To
> check this, right-click on the project, select "Properties", browse to
> "Configuration Properties > General" and find the "Common Language
> Runtime Support" field. It should read "Common Language Runtime
> Support (/clr)" or similar.
>
> Let me also say, if you are using C++/CLI (Managed C++) then I would
> recommend calling the native ITK classes directly (ie. not to use
> ManagedITK). This approach allows you direct access to the ITK
> modules, rather than going through an intermediate wrapper
> (ManagedITK). Obviously for other CLR languages (C#, IronPython, etc.)
> this is not an option, so the wrapper must be used. You may want to
> look at the following Insight Users post for some advice if you decide
> to go down that path:
> http://public.kitware.com/pipermail/insight-users/2006-October/019652.html
>
> If you still want to use ManagedITK from C++/CLI then it can done in
> the following manner:
> 1. Open Visual Studio
> 2. Select File > New Project
> 3. Expand "Visual C++" and select "CLR"
> 4. Choose "CLR Console Application" or "Windows Forms Application"
> 5. Right-click the project, select "Properties", browse to
> "Configuration Properties > General > C++", add the directory
> containing the ManagedITK assemblies to the "Resolve #using
> References" field
> 6. At the top of you code, add a #using statement for each assembly
> you want to reference: eg. #using
> 7. Construct your filter pipeline
> 8. Build the project
> 9. Copy the required ManagedITK assemblies to the output directory
>
> Here is an example of a Console application I quickly created and
> verified works correctly (a Windows Form application would look very
> similar):
>
> // ManagedItkCpp.cpp : main project file.
>
> #include "stdafx.h"
> #using
> #using
>
> using namespace System;
>
> int main(array ^args)
> {
> // Read image
> Console::WriteLine(L"Reading input...");
> itk::itkImage_F2^ input = itk::itkImage_F2::New();
> input->Read("C:/Temp/cthead1.png");
>
> // Create filter
> Console::WriteLine(L"Setting up filter...");
> itk::itkBinaryThresholdImageFilter_IF2IF2^ filter =
> itk::itkBinaryThresholdImageFilter_IF2IF2::New();
> filter->SetInput(input);
> int lower = 100; int upper = 255;
> int inside = 255; int outside = 0;
> filter->LowerThreshold = gcnew itk::itkPixel_F(lower);
> filter->UpperThreshold = gcnew itk::itkPixel_F(upper);
> filter->InsideValue = gcnew itk::itkPixel_F(inside);
> filter->OutsideValue = gcnew itk::itkPixel_F(outside);
>
> // Run filter and write output
> Console::WriteLine(L"Running filter...");
> itk::itkImage_F2^ output = itk::itkImage_F2::New();
> filter->GetOutput(output);
> filter->Update();
> Console::WriteLine(L"Writing output...");
> output->Write("C:/Temp/cthead1-Threshold.mhd");
> return 0;
> }
>
> HTH
>
> Cheers, Dan
> dan dot muel at gmail dot com
>
> On 18/09/2007, Young wrote:
> > Hi Dan,
> >
> > I want to use Managed ITK Segmentation functions with my own application
> of Managed C++ (Window Forms, CLR, MSVC 8.0). But I have problems calling
> ITK object directly in Cpp files. Whenever I create an object, the compiler
> complaints "error C3767: candidate functions(s) not accessible".
> >
> > I know there are C# examples you made, but it's hard for me to create C++
> conversion from them. I could probably make library in C# and call it in
> C++, but I just think it should not be necessary with all existing itk
> mamaged library.
> > Do you also have C++ examples for recent Managed ITK too?
> > Or any couple of examples if not?
> >
> > Thanks,
> > Young


More information about the Insight-users mailing list