Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Dec 5th, 2006, 12:03 PM   #1
Klipt
Hobbyist Programmer
 
Join Date: Dec 2005
Posts: 118
Rep Power: 0 Klipt is an unknown quantity at this point
Combining C++ and C#

Wasn't sure whether to put this in the this forum or the C# one ... anyway...

Is it possible to write a nice user interface in C# but get it to call a number-crunching routine written in C++ (and compiled to native code, rather than bytecode)? Can Visual Studio 2005 version still compile its C++ code natively or is everything tied CLI runtime now? (If not, I suppose I'll have to look into mingw's DLL capabilities...)

The only info I've found about code mixing so far involves DLL's. I think I've got the C# part working (see end of the post - it's supposed to call a function from the DLL which as an experiment should do what the commented out C# code did)

But I'm not sure how to create the DLL in the first place. The new project wizard seems to give options for 'MFC DLL's and 'COM DLL's and so on ... is it possible to compile a 'normal' DLL?

Or even better, is there a way to do this without DLLs?

csharp Syntax (Toggle Plain Text)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Drawing.Imaging;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Runtime.InteropServices;
  10.  
  11. namespace DLLUser
  12. {
  13. public partial class frmDLLUser : Form
  14. {
  15. Bitmap bmp;
  16. Graphics gr;
  17. Random rand;
  18.  
  19. public frmDLLUser()
  20. {
  21. InitializeComponent();
  22. }
  23.  
  24. private void Form1_Load(object sender, EventArgs e)
  25. {
  26. bmp = new Bitmap(100, 100);
  27. gr = pnlPaint.CreateGraphics();
  28. rand = new Random();
  29. }
  30.  
  31. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  32. private struct STRUCT_DLL
  33. {
  34. public IntPtr scan0;
  35. public Int32 width;
  36. public Int32 height;
  37. public Int32 stride;
  38. }
  39.  
  40. [DllImport("draw_dll.dll")]
  41. private static extern void func_dll(
  42. ref STRUCT_DLL s
  43. );
  44.  
  45. private void btnRand_Click(object sender, EventArgs e)
  46. {
  47. BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  48.  
  49. STRUCT_DLL struct_dll = new STRUCT_DLL();
  50. struct_dll.scan0 = data.Scan0;
  51. struct_dll.width = data.Width;
  52. struct_dll.height = data.Height;
  53. struct_dll.stride = data.Stride;
  54.  
  55. func_dll(ref struct_dll);
  56.  
  57. /*unsafe
  58.   {
  59.   byte* imgPtr = (byte*)(data.Scan0);
  60.   for (int i = 0; i < data.Height; i++)
  61.   {
  62.   for (int j = 0; j < data.Width; j++)
  63.   {
  64.   *imgPtr = (byte)rand.Next(256);
  65.   *(imgPtr + 1) = (byte)rand.Next(256);
  66.   *(imgPtr + 2) = (byte)rand.Next(256);
  67.  
  68.   imgPtr += 3;
  69.   }
  70.   imgPtr += data.Stride - data.Width * 3;
  71.   }
  72.   }*/
  73.  
  74. bmp.UnlockBits(data);
  75.  
  76. gr.DrawImage(bmp, new Point(0, 0));
  77. }
  78.  
  79. private void pnlPaint_Paint(object sender, PaintEventArgs e)
  80. {
  81. gr.DrawImage(bmp, new Point(0, 0));
  82. }
  83. }
  84. }

(places I've looked:
http://www.adp-gmbh.ch/csharp/call_dll.html
http://www.codersource.net/csharp_image_Processing.aspx for the bitmap stuff)
Klipt is offline   Reply With Quote
Old Dec 5th, 2006, 12:20 PM   #2
Narue
Professional Programmer
 
Narue's Avatar
 
Join Date: Sep 2005
Posts: 419
Rep Power: 4 Narue is on a distinguished road
You can mix and match .NET languages, so an assembly written in C++/CLI will mesh with an assembly written in C#. However, if you want to mix native C++ with a .NET assembly, you pretty much need to create a DLL in C++ and then uglify your C# to connect to it.
__________________
Even if the voices aren't real, they have some pretty good ideas.
Narue is offline   Reply With Quote
Old Dec 5th, 2006, 1:03 PM   #3
Klipt
Hobbyist Programmer
 
Join Date: Dec 2005
Posts: 118
Rep Power: 0 Klipt is an unknown quantity at this point
Yes, it looks like things will get ugly...

It seems that to create a 'normal' DLL you have to create a C++ 'console project' and then select the DLL option, instead of being distracted by all the things that mention DLLs on the first step.

All hail the great Microsoft for making things easy to find.
Klipt is offline   Reply With Quote
Old Dec 5th, 2006, 1:35 PM   #4
Klipt
Hobbyist Programmer
 
Join Date: Dec 2005
Posts: 118
Rep Power: 0 Klipt is an unknown quantity at this point
Woah, that last link I found actually got it working IT'S ALIVE!

Thanks for the input.
Klipt is offline   Reply With Quote
Old Dec 5th, 2006, 5:37 PM   #5
Polyphemus_
Expert Programmer
 
Polyphemus_'s Avatar
 
Join Date: Aug 2005
Location: Rotterdam, the Netherlands
Posts: 942
Rep Power: 4 Polyphemus_ is on a distinguished road
You could use Managed C++ as well. Managed C++ uses the .NET framework, but can be integrated very easily with native C++ (even in the same source file), by using the #pragma unmanaged tags.

I use it myself now for a relatively big project, and it works like a charm: the ease of use of the .NET framework and the speed of native code. No ugly DLL function declarations or anything - it just works.
Polyphemus_ is offline   Reply With Quote
Old Dec 7th, 2006, 10:09 AM   #6
Klipt
Hobbyist Programmer
 
Join Date: Dec 2005
Posts: 118
Rep Power: 0 Klipt is an unknown quantity at this point
Thanks, I'll look into that.
Klipt is offline   Reply With Quote
Old Dec 12th, 2006, 12:45 PM   #7
Klipt
Hobbyist Programmer
 
Join Date: Dec 2005
Posts: 118
Rep Power: 0 Klipt is an unknown quantity at this point
Ok, I added and referenced a C++ project in a C# solution, and it compiles fine, but when it tries to access the C++ code during runtime it says:

System.IO.FileLoadException was unhandled
Message="Attempt to load an unverifiable executable with fixups (IAT with more than 2 sections or a TLS section.) (Exception from HRESULT: 0x80131019)"

I tried putting the C# call in an 'unsafe' block but it made no difference. Any ideas as to where I'm being stupid? :p

The C# code is in a button click event:
csharp Syntax (Toggle Plain Text)
  1. Adder b;
  2. int c = b.add1(5);
  3. btnClick.Text = c.ToString();

C++ header:
cpp Syntax (Toggle Plain Text)
  1. #ifndef CALC_H
  2. #define CALC_H
  3.  
  4. #pragma managed
  5.  
  6. public value class Adder
  7. {
  8. public:
  9. int add1(int a);
  10. };
  11.  
  12. #endif

C++ code:
cpp Syntax (Toggle Plain Text)
  1. #include "Calc.h"
  2. #include <iostream>
  3.  
  4. #pragma managed
  5.  
  6. int Adder::add1(int a)
  7. {
  8. return a+1;
  9. }
  10.  
  11. int Main()
  12. {
  13. return 0;
  14. }
Klipt is offline   Reply With Quote
Old Dec 12th, 2006, 1:05 PM   #8
Klipt
Hobbyist Programmer
 
Join Date: Dec 2005
Posts: 118
Rep Power: 0 Klipt is an unknown quantity at this point
I changed a compiler option for the C++ project to "Pure MSIL Common Language Runtime Support (/clr : pure)" and now it works. But now the assembly can't contain unmanaged code...

I assume this means that C# can't interface nicely with mixed C++ assemblies - you'd have to wrap the mixed C++ with another "pure MSIL" C++ class and only call the "pure MSIL" wrapper from C#? ---EDIT - seems to give the same error.

Or ditch the C# and use a 'windows forms' managed C++ GUI?

Last edited by Klipt; Dec 12th, 2006 at 1:22 PM.
Klipt is offline   Reply With Quote
Old Dec 12th, 2006, 1:35 PM   #9
Polyphemus_
Expert Programmer
 
Polyphemus_'s Avatar
 
Join Date: Aug 2005
Location: Rotterdam, the Netherlands
Posts: 942
Rep Power: 4 Polyphemus_ is on a distinguished road
Yes, I suggest dropping C# and doing everything in C++/CLI. Almost the same as it uses the same framework, and it makes things a lot easier.
Polyphemus_ is offline   Reply With Quote
Old Dec 12th, 2006, 3:16 PM   #10
Klipt
Hobbyist Programmer
 
Join Date: Dec 2005
Posts: 118
Rep Power: 0 Klipt is an unknown quantity at this point
Hmm ... ease of Delphi and power of C++ ... very tempting

I finally found what I was doing wrong above: trying to link to a mixed .exe. I changed the C++ project to a DLL and it worked fine. So it seems C# can link easily to a mixed or pure .dll, but only to a pure .exe. Writing a managed wrapper for the unmanaged functions only saves you from [importing functions explicitly].
Klipt is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Combining strings for os.system() peaceofpi Python 12 Sep 14th, 2006 7:35 AM
Combining languages titaniumdecoy Other Programming Languages 12 Jul 13th, 2006 2:03 PM
Combining Values in an array bigmitch C++ 4 Feb 10th, 2006 7:29 AM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 7:43 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC