Search Unity

more bundle trouble...

Discussion in 'Scripting' started by Cav, Aug 10, 2006.

  1. Cav

    Cav

    Joined:
    Aug 2, 2006
    Posts:
    93
    Hi,

    can anyone offer any help here..i have simplified all of the code to the bare minumum of the problem. so at the moment im sending a number (at every 20th iteration of the update) from my script through to the C bundle where i add one to it and return the result to be printed.

    at the moment the problem is that it is printing "counter1 = " from 0 to 20, then "counter2 = 0" and then the result of adding one to 'number' which is apparently -1073749583.

    thanks for any help!


    First Script:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MidiBoxes : MonoBehaviour {
    5.  
    6.     int counter = 0;
    7.     int number = 0;
    8.  
    9.     void Awake ()
    10.     {
    11.     }
    12.        
    13.     void Update ()
    14.     {
    15.         counter ++;
    16.  
    17.         print("Counter1 = " +counter);
    18.  
    19.         if (counter == 20)
    20.         {
    21.             number = MidiPlugin.AddOne(number);
    22.             counter = 0;
    23.             print("Counter2 = " +counter);
    24.             print("Number = " +number);
    25.         }
    26.         //print(MidiPlugin.AddOne());
    27.        
    28.     }
    29. }

    Second Script:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4. using System.Runtime.InteropServices;
    5.  
    6. public class MidiPlugin
    7. {
    8.     public static int AddOne(int number)
    9.     {
    10.         int number1 = Testing(out number);
    11.         return number1;
    12.     }
    13.    
    14.         [DllImport ("UnityMidi")]
    15.     private static extern int Testing (out int passIn);
    16.  
    17. }


    'Bundle':

    Code (csharp):
    1. #include "UnityMidi.h"
    2. #include <vector>
    3. #include <pthread.h>
    4.  
    5. static std::vector<MIDIEndpointRef> gMidiSources;
    6. std::list<MidiMessage>              gMidiMessageBuffer;
    7. static pthread_mutex_t              gMutex;
    8. static MIDIClientRef                gMidiClient = NULL;
    9. static MIDIPortRef                  gMidiPort = NULL;
    10.  
    11. int Testing(int passIn)
    12. {
    13.     passIn += 1;
    14.     return passIn;
    15. }
     
  2. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    The declarations don't match.

    On the C++ side the function is declared as taking an int parameter passed by value.

    On the C# side it is defined to be an output parameter. This means that it is passed by reference.

    So the weird number you are seeing is the address of the number variable in the C# code. (Cast to a signed integer.)

    Try removing the "out" modifier from the C# definition.

    If you really need the function to modify its parameter (in your example you are not using it that way), you might be able to get away with defining the parameter to be a pointer to int:
    Code (csharp):
    1.  
    2. int Testing(int *passIn)
    3. {
    4.    (*passIn) += 1;
    5.    return *passIn;
    6. }
    7.  
     
  3. Cav

    Cav

    Joined:
    Aug 2, 2006
    Posts:
    93
    thanks for the help....

    This gives the error: 'argument must be passed with the out keyword'

    at this stage I dont fully understand the use of the 'out' keyword...can anyone explain it?

    changing the C++ code as you showed does not work because then the C# code gives an entry point not found Exception when sending the int.

    still working at it!
     
  4. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    You'll have to remove the 'out' both where you define the function and where you call it.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System;
    5. using System.Runtime.InteropServices;
    6.  
    7. public class MidiPlugin
    8. {
    9.    public static int AddOne(int number)
    10.    {
    11.       int number1 = Testing(number);
    12.       return number1;
    13.    }
    14.    
    15.       [DllImport ("UnityMidi")]
    16.    private static extern int Testing (int passIn);
    17.  
    18. }
    19.  

    It means that if the argument is modified by the called function, the caller's variable will get modified as well.

    See http://msdn2.microsoft.com/en-us/library/t3c3bfhx.aspx for more info on the 'out' keyword.
     
  5. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    C++ mangles the internal names for functions to support overloading. To avoid this declare the function as extern "C"
     
  6. Cav

    Cav

    Joined:
    Aug 2, 2006
    Posts:
    93
    sorry, i failed to mention and include the bundle header file that declares the method as extern C....all the same:

    Now works! thanks very much, in my haste had forgotten to remove the 'out' where i import the C++ method.

    on a side note is this the best way to send information back and forth between C# and C++ scripts? In the event of the project being realised to its full potential there will be a high rate of information going both ways.
     
  7. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    Ah, but did you remember to change the signature of the function in the header file to match the modified one? (i.e change the int to int* there as well)