CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Jun 2011
    Location
    CT
    Posts
    7

    How do I convert a C# code to C++?

    http://weblogs.sqlteam.com/mladenp/a...tion-in-C.aspx
    Is there someone who can help me convert this code to C++?

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How do I convert a C# code to C++?

    Do you realize you'll also need to convert the library the code uses?

    Lately I've been doing some image processing work using the most amazing AForge.NET open source library written in C#.

  3. #3
    Join Date
    Jun 2011
    Location
    CT
    Posts
    7

    Re: How do I convert a C# code to C++?

    No, I didn't know that... well, I'll leave that part alone for now. I just want to focus on getting the rest of the code converted. Is this something you could help me with? If it's not too much trouble, I mean. *sheepish* Thank you for taking time to read my post and reply. I appreciate it. ^^

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How do I convert a C# code to C++?

    It isn't going to make much sense to convert the code if you don't have a C++ Image library.

    In other words, how you approach writing this code in C++ will depend on the Image library you use.

  5. #5
    Join Date
    Jun 2011
    Location
    CT
    Posts
    7

    Re: How do I convert a C# code to C++?

    I honestly don't know. I was told to try and convert this code to C++. I'm really new at this. /:

    See, I'm working for my professor who is the head of the Computer Science department, and also the guy behind the Center for Graphics Research. There's three of us doing research and other tasks, and the task assigned to me was to convert that code into C++. I don't know why he asked me to do it - I only just finished my first C++ class this Spring semester, so I have no idea how to do this. The only programming knowledge I have was from taking Java last fall and C++ this spring.

    I'm going to be really embarrassed if I show up with nothing accomplished. I've been searching Google, but I haven't come across anything that could help me.

    If you have any advice or helpful tips, I'd really appreciate it. And thank you for taking your time to read my post. ^^;;

  6. #6
    Join Date
    Aug 2005
    Posts
    198

    Re: How do I convert a C# code to C++?

    If you want C++/CLI (using .NET), then it's fairly simple.
    It's probably not what you want, but just in case here it is:

    Code:
    using namespace System;
    using namespace System::Collections::Generic;
    using namespace System::Text;
    
    namespace Segmentation
    {
    	public ref class WatershedPixel
    	{
    	public:
    		int X;
    		int Y;
    		int Height;
    		// labels the pixel as belonging to a unique basin or as a part of the watershed line
    		int Label;
    		// Distance is a work image of distances
    		int Distance;
    
    		WatershedPixel()
    		{
    			this->X = -1;
    			this->Y = -1;
    			this->Height = -1000;
    			this->Label = -1000;
    			this->Distance = -1000;
    		}
    
    		WatershedPixel(int x, int y)
    		{
    			this->X = x;
    			this->Y = y;
    			this->Height = -1000;
    			this->Label = WatershedCommon->INIT;
    			this->Distance = 0;
    		}
    
    		WatershedPixel(int x, int y, int height)
    		{
    			this->X = x;
    			this->Y = y;
    			this->Height = height;
    			this->Label = WatershedCommon->INIT;
    			this->Distance = 0;
    		}
    
    		virtual bool Equals(Object ^obj) override
    		{
    			WatershedPixel ^p = safe_cast<WatershedPixel^>(obj);
    			return (X == p->X && X == p->Y);
    		}
    
    		virtual int GetHashCode() override
    		{
    			return X;
    		}
    		virtual String ^ToString() override
    		{
    			return "Height = " + Height + "; X = " + X.ToString() + ", Y = " + Y.ToString() + "; Label = " + Label.ToString() + "; Distance = " + Distance.ToString();
    		}
    	};
    
    	public ref class WatershedGrayscale : FilterGrayToGray
    	{
    		#pragma region Variables
    	private:
    		WatershedPixel ^FictitiousPixel;
    		int _currentLabel;
    		int _currentDistance;
    		FifoQueue ^_fifoQueue;
    		// each pixel can be accesesd from 2 places: a dictionary for faster direct lookup of neighbouring pixels 
    		// or from a height ordered list
    		// sorted array of pixels according to height
    		List<List<WatershedPixel^>^> ^_heightSortedList;
    		// string in the form "X,Y" is used as a key for the dictionary lookup of a pixel
    		Dictionary<String^, WatershedPixel^> ^_pixelMap;
    		int _watershedPixelCount;
    		int _numberOfNeighbours;
    		bool _borderInWhite;
    		int _pictureWidth;
    		int _pictureHeight;
    		#pragma endregion
    
    		#pragma region Constructors
    	public:
    //C# TO C++ CONVERTER TODO TASK: Calls to same-class constructors are not supported in C++:
    //ORIGINAL LINE: public WatershedGrayscale() : this(8)
    		WatershedGrayscale()
    		{
    		InitializeInstanceFields();
    		}
    
    		WatershedGrayscale(int numberOfNeighbours)
    		{
    			InitializeInstanceFields();
    			if (numberOfNeighbours != 8 && numberOfNeighbours != 4)
    				throw gcnew Exception("Invalid number of neighbour pixels to check. Valid values are 4 and 8.");
    			_borderInWhite = true;
    			_numberOfNeighbours = numberOfNeighbours;
    			_heightSortedList = gcnew List<List<WatershedPixel^>^>(256);
    			for (int i = 0; i < 256; i++)
    				_heightSortedList->Add(gcnew List<WatershedPixel^>());
    		}
    		#pragma endregion
    
    		#pragma region Properties
    		/// <summary>
    		/// number of neighbours to check for each pixel. valid values are 8 and 4
    		/// </summary>
    		property int NumberOfNeighbours
    		{
    			int get()
    			{
    				return _numberOfNeighbours;
    			}
    			void set(int value)
    			{
    				if (value != 8 && value != 4)
    					throw gcnew Exception("Invalid number of neighbour pixels to check. Valid values are 4 and 8.");
    				_numberOfNeighbours = value;
    			}
    		}
    
    		/// <summary>
    		/// Number of labels/basins found
    		/// </summary>
    		property int LabelCount
    		{
    			int get()
    			{
    				return _currentLabel;
    			}
    			void set(int value)
    			{
    				_currentLabel = value;
    			}
    		}
    
    		/// <summary>
    		/// True: border is drawn in white. False: border is drawn in black
    		/// </summary>
    		/// <value></value>
    		property bool BorderInWhite
    		{
    			bool get()
    			{
    				return _borderInWhite;
    			}
    			void set(bool value)
    			{
    				_borderInWhite = value;
    			}
    		}
    		#pragma endregion
    
    	private:
    		void CreatePixelMapAndHeightSortedArray(BitmapData ^data)
    		{
    			_pictureWidth = data->Width;
    			_pictureHeight = data->Height;
    			// pixel map holds every pixel thus size of (_pictureWidth * _pictureHeight)
    			_pixelMap = gcnew Dictionary<String^, WatershedPixel^>(_pictureWidth * _pictureHeight);
    //			unsafe
    				int offset = data->Stride - data->Width;
    				Byte* ptr = (Byte*)(data->Scan0);
    
    				// get histogram of all values in grey = height
    				for (int y = 0; y < data->Height; y++)
    				{
    					for (int x = 0; x < data->Width; x++, ptr++)
    					{
    						WatershedPixel ^p = gcnew WatershedPixel(x, y, *ptr);
    						// add every pixel to the pixel map
    						_pixelMap->Add(p->X.ToString() + "," + p->Y.ToString(), p);
    						_heightSortedList[*ptr]->Add(p);
    					}
    					ptr += offset;
    				}
    //C# TO C++ CONVERTER NOTE: End of the original C# 'unsafe' block
    			this->_currentLabel = 0;
    		}
    
    		void Segment()
    		{
    			// Geodesic SKIZ (skeleton by influence zones) of each level height
    			for (int h = 0; h < _heightSortedList->Count; h++)
    			{
    				// get all pixels for current height
    				for each (WatershedPixel ^heightSortedPixel in _heightSortedList[h])
    				{
    					heightSortedPixel->Label = WatershedCommon->MASK;
    					// for each pixel on current height get neighbouring pixels
    					List<WatershedPixel^> ^neighbouringPixels = GetNeighbouringPixels(heightSortedPixel);
    					// initialize queue with neighbours at level h of current basins or watersheds
    					for each (WatershedPixel ^neighbouringPixel in neighbouringPixels)
    					{
    						if (neighbouringPixel->Label > 0 || neighbouringPixel->Label == WatershedCommon->WSHED)
    						{
    							heightSortedPixel->Distance = 1;
    							_fifoQueue->AddToEnd(heightSortedPixel);
    							break;
    						}
    					}
    				}
    				_currentDistance = 1;
    				_fifoQueue->AddToEnd(FictitiousPixel);
    				// extend basins
    				while (true)
    				{
    					WatershedPixel ^p = _fifoQueue->RemoveAtFront();
    					if (p->Equals(FictitiousPixel))
    					{
    						if (_fifoQueue->IsEmpty)
    							break;
    						else
    						{
    							_fifoQueue->AddToEnd(FictitiousPixel);
    							_currentDistance++;
    							p = _fifoQueue->RemoveAtFront();
    						}
    					}
    					List<WatershedPixel^> ^neighbouringPixels = GetNeighbouringPixels(p);
    					// labelling p by inspecting neighbours
    					for each (WatershedPixel ^neighbouringPixel in neighbouringPixels)
    					{
    						// neighbouringPixel belongs to an existing basin or to watersheds
    						// in the original algorithm the condition is:
    						//   if (neighbouringPixel.Distance < currentDistance && 
    						//      (neighbouringPixel.Label > 0 || neighbouringPixel.Label == WatershedCommon.WSHED))
    						//   but this returns incomplete borders so the this one is used                        
    						if (neighbouringPixel->Distance <= _currentDistance && (neighbouringPixel->Label > 0 || neighbouringPixel->Label == WatershedCommon->WSHED))
    						{
    							if (neighbouringPixel->Label > 0)
    							{
    								// the commented condition is also in the original algorithm 
    								// but it also gives incomplete borders
    								if (p->Label == WatershedCommon->MASK) //|| p.Label == WatershedCommon.WSHED
    									p->Label = neighbouringPixel->Label;
    								else if (p->Label != neighbouringPixel->Label)
    								{
    									p->Label = WatershedCommon->WSHED;
    									_watershedPixelCount++;
    								}
    							}
    							else if (p->Label == WatershedCommon->MASK)
    							{
    								p->Label = WatershedCommon->WSHED;
    								_watershedPixelCount++;
    							}
    						}
    						// neighbouringPixel is plateau pixel
    						else if (neighbouringPixel->Label == WatershedCommon->MASK && neighbouringPixel->Distance == 0)
    						{
    							neighbouringPixel->Distance = _currentDistance + 1;
    							_fifoQueue->AddToEnd(neighbouringPixel);
    						}
    					}
    				}
    				// detect and process new minima at height level h
    				for each (WatershedPixel ^p in _heightSortedList[h])
    				{
    					// reset distance to zero
    					p->Distance = 0;
    					// if true then p is inside a new minimum 
    					if (p->Label == WatershedCommon->MASK)
    					{
    						// create new label
    						_currentLabel++;
    						p->Label = _currentLabel;
    						_fifoQueue->AddToEnd(p);
    						while (!_fifoQueue->IsEmpty)
    						{
    							WatershedPixel ^q = _fifoQueue->RemoveAtFront();
    							// check neighbours of q
    							List<WatershedPixel^> ^neighbouringPixels = GetNeighbouringPixels(q);
    							for each (WatershedPixel ^neighbouringPixel in neighbouringPixels)
    							{
    								if (neighbouringPixel->Label == WatershedCommon->MASK)
    								{
    									neighbouringPixel->Label = _currentLabel;
    									_fifoQueue->AddToEnd(neighbouringPixel);
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    
    		List<WatershedPixel^> ^GetNeighbouringPixels(WatershedPixel ^centerPixel)
    		{
    			List<WatershedPixel^> ^temp = gcnew List<WatershedPixel^>();
    			if (_numberOfNeighbours == 8)
    			{
    				/*
    				CP = Center pixel
    				(X,Y) -- get all 8 connected 
    				|-1,-1|0,-1|1,-1|
    				|-1, 0| CP |1, 0|
    				|-1,+1|0,+1|1,+1|
    				*/                
    				// -1, -1                
    				if ((centerPixel->X - 1) >= 0 && (centerPixel->Y - 1) >= 0)
    					temp->Add(_pixelMap[(centerPixel->X - 1)->ToString() + "," + (centerPixel->Y - 1)->ToString()]);
    				//  0, -1
    				if ((centerPixel->Y - 1) >= 0)
    					temp->Add(_pixelMap[centerPixel->X.ToString() + "," + (centerPixel->Y - 1)->ToString()]);
    				//  1, -1
    				if ((centerPixel->X + 1) < _pictureWidth && (centerPixel->Y - 1) >= 0)
    					temp->Add(_pixelMap[(centerPixel->X + 1)->ToString() + "," + (centerPixel->Y - 1)->ToString()]);
    				// -1, 0
    				if ((centerPixel->X - 1) >= 0)
    					temp->Add(_pixelMap[(centerPixel->X - 1)->ToString() + "," + centerPixel->Y.ToString()]);
    				//  1, 0
    				if ((centerPixel->X + 1) < _pictureWidth)
    					temp->Add(_pixelMap[(centerPixel->X + 1)->ToString() + "," + centerPixel->Y.ToString()]);
    				// -1, 1
    				if ((centerPixel->X - 1) >= 0 && (centerPixel->Y + 1) < _pictureHeight)
    					temp->Add(_pixelMap[(centerPixel->X - 1)->ToString() + "," + (centerPixel->Y + 1)->ToString()]);
    				//  0, 1
    				if ((centerPixel->Y + 1) < _pictureHeight)
    					temp->Add(_pixelMap[centerPixel->X.ToString() + "," + (centerPixel->Y + 1)->ToString()]);
    				//  1, 1
    				if ((centerPixel->X + 1) < _pictureWidth && (centerPixel->Y + 1) < _pictureHeight)
    					temp->Add(_pixelMap[(centerPixel->X + 1)->ToString() + "," + (centerPixel->Y + 1)->ToString()]);
    			}
    			else
    			{
    				/*
    				CP = Center pixel, N/A = not used
    				(X,Y) -- get only 4 connected 
    				| N/A |0,-1| N/A |
    				|-1, 0| CP |+1, 0|
    				| N/A |0,+1| N/A |
    				*/
    				//  -1, 0
    				if ((centerPixel->X - 1) >= 0)
    					temp->Add(_pixelMap[(centerPixel->X - 1)->ToString() + "," + centerPixel->Y.ToString()]);
    				//  0, -1
    				if ((centerPixel->Y - 1) >= 0)
    					temp->Add(_pixelMap[centerPixel->X.ToString() + "," + (centerPixel->Y - 1)->ToString()]);
    				//  1, 0
    				if ((centerPixel->X + 1) < _pictureWidth)
    					temp->Add(_pixelMap[(centerPixel->X + 1)->ToString() + "," + centerPixel->Y.ToString()]);
    				//  0, 1
    				if ((centerPixel->Y + 1) < _pictureHeight)
    					temp->Add(_pixelMap[centerPixel->X.ToString() + "," + (centerPixel->Y + 1)->ToString()]);
    			}
    			return temp;
    		}
    
    		void DrawWatershedLines(BitmapData ^data)
    		{
    			if (_watershedPixelCount == 0)
    				return;
    
    			Byte watershedColor = 255;
    			if (!_borderInWhite)
    				watershedColor = 0;
    //			unsafe
    				int offset = data->Stride - data->Width;
    				Byte* ptr = (Byte*)(data->Scan0);
    
    				for (int y = 0; y < data->Height; y++)
    				{
    					for (int x = 0; x < data->Width; x++, ptr++)
    					{
    						// if the pixel in our map is watershed pixel then draw it
    						if (_pixelMap[x.ToString() + "," + y.ToString()]->Label == WatershedCommon->WSHED)
    							*ptr = watershedColor;
    					}
    					ptr += offset;
    				}
    //C# TO C++ CONVERTER NOTE: End of the original C# 'unsafe' block
    		}
    
    	protected:
    		virtual void ProcessFilter(BitmapData ^imageData) override
    		{
    			CreatePixelMapAndHeightSortedArray(imageData);
    			Segment();
    			DrawWatershedLines(imageData);
    		}
    
    	private:
    		bool initialized;
    		void InitializeInstanceFields()
    		{
    			if ( ! initialized)
    			{
    				FictitiousPixel = gcnew WatershedPixel();
    				_fifoQueue = gcnew FifoQueue();
    				_numberOfNeighbours = 8;
    
    				initialized = true;
    			}
    		}
    	};
    
    	public ref class FifoQueue
    	{
    	private:
    		List<WatershedPixel^> ^queue;
    
    	public:
    		property int Count
    		{
    			int get()
    			{
    				return queue->Count;
    			}
    		}
    
    		void AddToEnd(WatershedPixel ^p)
    		{
    			queue->Add(p);
    		}
    
    		WatershedPixel ^RemoveAtFront()
    		{
    			WatershedPixel ^temp = queue[0];
    			queue->RemoveAt(0);
    			return temp;
    		}
    
    		property bool IsEmpty
    		{
    			bool get()
    			{
    				return (queue->Count == 0);
    			}
    		}
    
    		virtual String ^ToString() override
    		{
    			return __super::ToString() + " Count = " + queue->Count.ToString();
    		}
    
    	private:
    		bool initialized;
    		void InitializeInstanceFields()
    		{
    			if ( ! initialized)
    			{
    				queue = gcnew List<WatershedPixel^>();
    
    				initialized = true;
    			}
    		}
    
    public:
    	FifoQueue()
    	{
    		InitializeInstanceFields();
    	}
    	};
    
    	public ref class WatershedCommon
    	{
    		#pragma region Constants
    	public:
    		literal int INIT = -1;
    		literal int MASK = -2;
    		literal int WSHED = 0;
    		#pragma endregion
    	};
    }
    David Anton
    Convert between VB, C#, C++, & Java
    www.tangiblesoftwaresolutions.com
    Instant C# - VB to C# Converter
    Instant VB - C# to VB Converter

  7. #7
    Join Date
    Jun 2011
    Location
    CT
    Posts
    7

    Re: How do I convert a C# code to C++?

    First, I just want to thank you for taking the time to help me out. I'm extremely grateful.

    You said this might not be what I want - why is that? Just wondering.

  8. #8
    Join Date
    Aug 2005
    Posts
    198

    Re: How do I convert a C# code to C++?

    It's C++/CLI code which requires Visual C++ 2005 or higher.

    It works just like C# code, so you will have nearly identical performance as C# (slower than native C++).

    Also, your users will need to have the .NET Framework installed to run your app.
    David Anton
    Convert between VB, C#, C++, & Java
    www.tangiblesoftwaresolutions.com
    Instant C# - VB to C# Converter
    Instant VB - C# to VB Converter

  9. #9
    Join Date
    Jun 2011
    Location
    CT
    Posts
    7

    Re: How do I convert a C# code to C++?

    Oh, okay. Yeah, then it's probably not what I'm looking for then. What part of the code makes it have this requirement? Or is it throughout the code, being the way it's written?

  10. #10
    Join Date
    Aug 2005
    Posts
    198

    Re: How do I convert a C# code to C++?

    Both the syntax and the library dictate this requirement:

    1. The syntax is a Microsoft-unique thing that never really caught on much.
    2. The library used is .NET - the same as C#.
    David Anton
    Convert between VB, C#, C++, & Java
    www.tangiblesoftwaresolutions.com
    Instant C# - VB to C# Converter
    Instant VB - C# to VB Converter

  11. #11
    Join Date
    Jun 2011
    Location
    CT
    Posts
    7

    Re: How do I convert a C# code to C++?

    Ah, I see. Okay, thank you.

  12. #12
    Join Date
    Jun 2008
    Posts
    2,477

    Re: How do I convert a C# code to C++?

    Quote Originally Posted by David Anton View Post
    It works just like C# code, so you will have nearly identical performance as C# (slower than native C++).
    A bit off topic, but C#.NET has been shown time and time again to not be generally slower than C++. C or C++ shine when it comes to intense number crunching, but not all apps require that. C#'s built in collection classes are actually faster than the Microsoft implementation of analogous types, and C# also pulls ahead in many other areas. You will (probably) always be able to hand tune C or C++ to be faster than its managed counterpart, but for most apps it's a complete waste of time to do so.

  13. #13
    Join Date
    Jan 2010
    Posts
    1,133

    Re: How do I convert a C# code to C++?

    Did your professor asked you to do this as some sort of a test, or will the converted code going to actually be used for something? Is it OK for you to further discuss requirements with him? Does your professor has some experience with C#?

    You say that he is "the guy behind the Center for Graphics Research" - then maybe you have some in-house libraries that provide functionality similar to the one used in the article?
    If so, are these written in C++?

    And what is your target platform - native C++, or .NET?
    If it's native, you can't go with C++/CLI.

  14. #14
    Join Date
    Jun 2011
    Location
    CT
    Posts
    7

    Re: How do I convert a C# code to C++?

    It's not for class, it's a job. The platform is native C++.

    We're doing research, and the Watershed code is one of the research we found, but my professor wanted to convert it to C++.
    He doesn't know C#.

  15. #15
    Join Date
    Jan 2010
    Posts
    1,133

    Re: How do I convert a C# code to C++?

    Then you'll have to find an existing C++ image processing library to take the place of the .NET equivalent in the article (rather than rewriting AForge.NET in C++). As I've said, it is possible that your department already has something like that.

    C++/CLI is used for .NET-native interop, and for migrating legacy native apps to the .NET environment.
    .NET apps require .NET runtime in order to work, so if that is not an option, than neither is C++/CLI.

    Which means that you need to focus on how to implement the approach/algorithm in C++, and to identify the equivalent APIs in the image processing library you pick.

    You should be able to understand most of the code, since C# syntax is similar to C++. However there are certain important differences that may not be obvious to you - like reference and value types.

    So your first steps would be to (1) have a general understanding of the approach - the idea behind it, and (2) to find an adequate C++ library that provides the required functionality - your professor/colleagues can help you with that.

    EDIT:
    I just gave that code a more detailed look.
    It seems that it doesn't use the AForge.NET library at all - it just mentions it because, at the time of the writing, that library didn't support what the author was trying to accomplish.
    So, that eliminates the library problem. This is just a brute force approach.

    Have you already made some progress with the code? Or do you have a general idea how would you approach it? Or you're completely lost?
    Can you understand the C# code in the article by reading, and what are exactly your C++ skills? Any experience with C++ image processing before?
    Last edited by TheGreatCthulhu; June 21st, 2011 at 08:37 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured