Thread: multiple language project

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    37

    Question multiple language project

    I am trying to figure out how to properly construct a multi-language project. A simple one, and no it is not homework, such as a VB or C# form with a button and 2 listboxes. When the button is clicked, the left listbox displays the unsorted array and the right listbox displays the sorted array. Now this is easy enough to do in the same langauge but, if I write code for a bubblesort in C++ and try to call the C++ bubblesort function from VB or C# I get an error stating that the sortArray function (the C++ code) is not a member of BubbleSort. Can anyone help and possibly provide an example of how to write a multi-language project? All we ever hear is that it can be done in .NET but no book ever give you a clear example. I did compile the BubbleSort as a .dll and add it as a reference to my VB and C# (I tried them Both) forms but it still does not work. I will place the code for both projects below. Thanks for any help you can offer.

    Code:
    private void button1_Click(object sender, System.EventArgs e)
    {
       listBox1.Items.Add("The Unsorted Array:");
    			
       int[] unsortedArray = {72, 87, 32, 11, 6, 100, 91, 29, 81, 10};
       int[] sortedArray = new int[unsortedArray.Length];
    
       for (int i = 0; i < unsortedArray.Length; i++)
       {
           listBox1.Items.Add(unsortedArray[i]);
       }
    
      //call to C++ project to sort the array
       sortedArray = BubbleSort2.sortArray(unsortedArray,   
           unsortedArray.Length);
    
    
       listBox2.Items.Add("The Sorted Array:");
    
    }// end button1_click
    
       //Bubble sort code
    void sortArray(int data[], int elems)
    {
       int curSize = elems;
       int temp;
    
       bool swap = false;
    
       //for loop to process the array
       // decrements the loop after each pass
       for(curSize = elems; curSize >= 0; curSize--)
       {
           for(int i = 0; i <= elems; i++)
          {
             swap = true;
           
             // this checks to see if an array element is 
            // out of order and makes the swap.
            if(data[i] > data[i +1]) 				
            {
                temp = data[i];
                data[i] = data [i + 1];
                data[i+1] = temp;
            }//end if
         }//end for loop
        
          // breaks out of the loop when there is no more 
          // swapping to be done
          if(!swap) break;
    }//end function sortArray
    I hope that I have made the problem clear. I am just trying to figure out how to work with multiple language projects.

    Thanks,
    Alan

  2. #2
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    What does the C++ DLL code look like?

    I've done this before, you need to use DLLImport for the C#/VB.NET program, and then __dllexport for the C++ program. Something like that.

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    37
    I posted the C++ code above. It was just a simple bubblesort. If you are asking for the entire .dll file, I don't know if I can copy the entire thing. If you create a new project and tell .NET it is a .dll the rest was just the code above. I am not sure about the import/export thing. I have only read/been told that I had to include the .dll as a reference in the main project.

    Alan

  4. #4
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    My bad my bad lol

    You're going to want something like this in your C++ Program:
    Code:
    __declspec(dllexport) void sortArray(int data[], int elems);
    Then this in your C# code to be able to call sortArray:
    Code:
    using System.Runtime.InteropServices; // DllImport
    public class MyFunctions {
        [DllImport("TankCDR.dll")]
        public static extern void sortArray(int[] data,  IntPtr elems);
    }
    
    public class MyProgram {
        public static void Main() {
            int[] myArray = new int[] {2, 4, 1, 5, 3};
            MyFunctions.sortArray(myArray, 5);
        }
    }
    If I totally screwed up what the truth is, you might want to surf through this briefly:
    http://www.google.com/search?hl=en&q...=Google+Search

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    37
    That fixed all the errors. I had my fingers crossed when I tried to run it. It filled the left listbox with the unsorted array and bombed on the right listbox sayin that "an unhandled exception has occured. Unable to find an entry point named sortArray in DLL BubbleSort2.dll"

    It does not state that sortArray is not a member of Bubblesort2 anymore. It just cannot find an entry point. I do not know exactly what that means, but it apears that I am closer now.

    Alan

  6. #6
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    Some progress! Excellent! This is probably our problem:
    Code:
    __declspec(dllexport) void sortArray(int data[], int elems);
    Perhaps this might work:
    Code:
    extern "C" 
    {
         __declspec(dllexport) void sortArray(int data[], int elems);
    }
    Also, you may want to create a new project to test this out, make something simple:

    Code:
    __declspec(dllexport) void outputNumber(void);
    
    void outputNumber(void)
    {
         cout << "This is the C++ DLL!!!  AAAHHH!!" << endl;
    }
    And then in the C# file you could go:
    Code:
    public class MyFunctions 
    {
        [DllImport("TankCDR.dll")]
        public static extern void outputNumber();
    }
    If that works, then come back and we'll discuss some more DLL importing goodies! What I'm thinking your problem is, is that you may need to use C#'s IntPtr datatype instead of the int datatype, but we'll discuss that when you get the mini example working.

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    37
    I did not try what you typed in the last post yet but I thought that I would relay an interesting point. The problem does not have anything to do IntPtr in C#. I took out passing the variable altogether (in both the .dll file and in the C# program) and just hardcoded the for loops to stop at 10. It still gave me the entry point error. I will try you other example but I have come to the conclusion that if it is SO DIFFICULT to do what Microsoft uses as a selling tool then it probably is not worth the effort. Microsoft sells .NET saying you can put together these multi-language projects. But if the only thing that I can do in a multi-language project is pass a string, I do not need to code in more than one language.
    We are told that you can write the code in any language, compile it and you are good. But that is obviously a lie

    Thanks for your help but I am out of ideas,
    Alan

  8. #8
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    I know you can do this soldier, you've got to try harder! Once you reach the shore, you will be able to feel great about yourself because you can look at everyone else drowning! Anything is possible!

    Now do the mini examples, jeezus sqeezus. Guess/check is the best way to go.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    37
    I tried the simple string output and the .dll file blew up with many errors. So I changed it to just return a simple int (see below)

    [code]
    // This is the main DLL file.

    __declspec(dllexport) void outputNumber(void);

    #include "stdafx.h"

    #include "DllString.h"

    int outputNumber(void)
    {
    return 27;

    //cout << "This is the C++ DLL!!! AAAHHH!!" << endl;
    }
    {/code]

    In the C# code I get a similar error to before, it states:

    C:\Alan\VS Projects\MyFunctions\Form1.cs(110): The type or namespace name 'outputNumber' does not exist in the class or namespace 'DllString' (are you missing an assembly reference?)

    By the way,
    I liked your last post, it made me laugh.

    Alan

  10. #10
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    Code:
    // This is the main DLL file.
    __declspec(dllexport) void outputNumber(void); // <-- AAAHH!!!!! Bad return type!
    
    #include "stdafx.h"   // <-- AAAHH!!!!! Where did this come from!?
    
    #include "DllString.h" // <-- AAAHH!!!!! omg there's two of them!
    
    int outputNumber(void)
    {
        return 27;
        //cout << "This is the C++ DLL!!! AAAHHH!!" << endl;
    }
    Make sure your C++ DLL project is all empty except for the cpp file!..just to be safe. Make sure the C++ project is NOT Visual C++ but an empty unmanaged C++ project.

    You also may want to do this to the dllexport in the C++ DLL:
    Code:
    extern "C"
    {
        __declspec(dllexport) int outputNumber(void);
    }
    Also make sure when you build your solution that your DLL gets compiled before the C# project, and that the DLL gets put in the same directory with the C# .exe file.

  11. #11
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Howdy,

    TankCDR, does your C++ DLL have to be in managed (using the .NET runtime) or unmanaged (the old stinky stuff) C++?

    If it's unmanaged, it should be pretty easy.

    Code:
    BubbleSort.cpp - C++ Class
    
    // I've not written Managed C++ before so this syntax might be 
    // incorrect, if it is please remember to change it.
    namespace MyProject
    {
        public class BubbleSortTest
        {
            int outputNumber(void)
            {
                return 27;
                // The line below  is UNMANAGED C++. In 
                managed C++ you would write "Console::WriteLine(...)"
                //cout << "This is the C++ DLL!!! AAAHHH!!" << endl;    
            }
        }
    }
    Code:
    Form1.cs - C# Form
    [...]
    // Note they are in the same namespace
    namespace MyProject
    {
        class Form1 : Form
        {
            private void button1_Click(object sender, EventArgs e)
            {
                BubbleSortTest.outputNumber();
            }
        }
    }
    A note about Projects and References:
    The error you recieved earlier (The type or namespace name 'outputNumber' does not exist in the class or namespace 'DllString' (are you missing an assembly reference?)) is because your C# project was not referencing the C++ DLL. To compile you will need to add a reference to the C# project that tells it the C++ project exists.

    Assuming you are using Visual Studio .NET:
    Open the Solution Explorer (View->Solution Explorer) and right-click the C# project. Select Add Reference... and open the Projects tab. Select the C++ project and press OK. Now it should compile.

    (This message is akin to #including a file in unmanaged C++ but not adding a reference to the output or .CPP files in your project)

    If you have any problems please let me know!

    Paul

  12. #12
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,130
    We are told that you can write the code in any language, compile it and you are good. But that is obviously a lie.
    No, it's not. It's a misinterpretation on your part. This statement refers to .NET languages. You can compile a VB.NET dll and a C++.NET dll and link them to a C# application and it will magically just work.
    Note that C++.NET is managed C++. What you have is unmanaged C++ that was compiled with Visual Studio.NET, which does NOT make it C++.NET.

    You can also link to any unmanaged C++ dll or COM object very easily as shown in the technical posts above. All you have to know is the same information you would need to include the dll in your C++ projekt.
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic Binding
    By gpr1me in forum C++ Programming
    Replies: 1
    Last Post: 03-24-2006, 09:01 AM
  2. Phantom redefinition
    By CodeMonkey in forum C++ Programming
    Replies: 6
    Last Post: 06-12-2005, 05:42 PM
  3. How to add a file to a project in bloodshed.
    By Smeep in forum C++ Programming
    Replies: 4
    Last Post: 04-22-2005, 09:29 PM
  4. Socket Project (getting one of multiple clients IP)
    By Cl0wn in forum C Programming
    Replies: 2
    Last Post: 04-05-2003, 12:01 PM
  5. Including multiple .cpp file in project
    By bonkey in forum C++ Programming
    Replies: 2
    Last Post: 11-04-2002, 08:41 AM