none
vector of int parameter in a method marshaling RRS feed

  • Question

  • I have a c++ function like that:

    void Reshape(const vector<int>& shape){
    
        // some code
    
    }

    i have export this function and i need to call it from c# but my problem is how to pass the right argument to this method since it seems that there is no equivalent to C++  vector<int>  in c#


    • Edited by Raed lafi Tuesday, June 5, 2018 5:10 PM
    Tuesday, June 5, 2018 5:09 PM

All replies

  • Are you trying to pass data contained in a C# int[] array to the C++ function?

    One way would be to use a SAFEARRAY on the C++ side.

    • Edited by RLWA32 Tuesday, June 5, 2018 6:28 PM added SAFEARRAY suggestion
    Tuesday, June 5, 2018 6:26 PM
  • There are many possibilities, see the System.Collections.Generic Namespace.


    Sam Hobbs
    SimpleSamples.Info

    Tuesday, June 5, 2018 6:46 PM
  • i'm trying to find the equivalent of vector<int> in c# so i can pass it as argument to the function
    Wednesday, June 6, 2018 10:41 AM
  • i'm trying to find the equivalent of vector<int> in c# so i can pass it as argument to the function

    The Interop Marshaler doesn't know anything about C++ standard library vector templates.  See Default Marshaling for Arrays

    So you will need to pass the data from C# to C++ (with or without CLR support) and then convert it to a std::vector.

    Wednesday, June 6, 2018 11:01 AM
  • yes exactly, i have to change the c++ function si it accept array as argument, then convert the array to vector like this:

    void Reshape(const int foo[]){
         
         const vector<int>& shape ={}; // need to be 
                   //initialized else i will got error
    
        // Now need to convert the Foo[] array to shape vector
    
        // some code
    
    }

    My problem now is how to make the conversion from array to reference const vector?

    Friday, June 8, 2018 1:02 PM
  • yes exactly, i have to change the c++ function si it accept array as argument, then convert the array to vector like this:

    void Reshape(const int foo[]){
         
         const vector<int>& shape ={}; // need to be 
                   //initialized else i will got error
    
        // Now need to convert the Foo[] array to shape vector
    
        // some code
    
    }

    My problem now is how to make the conversion from array to reference const vector?

    Following examples show two different ways to pass a C# int[] array through P/Invoke to a C++ function.  The first example uses a SAFEARRAY and within the C++ function the content of the safearray is placed into a std::vector<int>.  I didn't bother to include the std::vector conversion in the second example of passing the C# array.

    Example 1 -

    Dll header "C" calling convention not shown

    __declspec(dllexport) void ReShape(SAFEARRAY **ppsa);

    C++ implementation -

    void ReShape(SAFEARRAY **ppsa)
    {
    	HRESULT hr;
    	int x;
    	LPVOID pData = NULL;
    	LONG lBound = -1, uBound = -1;
    	LPINT pInt = NULL;
    
    	hr = SafeArrayGetLBound(*ppsa, 1, &lBound);
    	hr = SafeArrayGetUBound(*ppsa, 1, &uBound);
    
    	int nElements = uBound - lBound + 1;
    
    	hr = SafeArrayAccessData(*ppsa, (LPVOID*) &pInt);
    
    	std::vector<int> vInt(pInt, pInt+nElements);
    
    	for (LONG i = lBound; i <= uBound; i++)
    	{
    		x = pInt[i];
    		pInt[i] = x + 10;
    	}
    
    	hr = SafeArrayUnaccessData(*ppsa);
    }


    The above code increments each element of the C# array by 10.  The changes are visible in the C# code that calls the function.

    Example 2 -

    Dll header "C" calling convention not shown -

    __declspec(dllexport) void ReShape2(int nElements, int *pElements);

    C++ implementation -

    void ReShape2(int nElements, int *pElements)
    {
    	int x;
    
    	for (int i = 0; i < nElements; i++)
    	{
    		x = pElements[i];
    		pElements[i] = x + 10;
    	}
    }

    C# Code to for P/Invoke -

    [DllImport("Bytes.dll", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
    static extern void ReShape([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType= VarEnum.VT_I4)] ref int[] iArray);
    
    [DllImport("Bytes.dll", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
    static extern void ReShape2(int nElements, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I4, SizeParamIndex = 1)] int[]  iArray);

    Call the functions with an array in C# - Note how the array values are increased.

                int[] aInts = { 1, 2, 3, 4, 5 };
    
                foreach ( int x in aInts)
                {
                    Console.WriteLine("Element is {0}", x);
                }
    
                ReShape(ref aInts);
    
                foreach (int x in aInts)
                {
                    Console.WriteLine("Element is {0}", x);
                }
    
                ReShape2(aInts.Count(), aInts);
    
                foreach (int x in aInts)
                {
                    Console.WriteLine("Element is {0}", x);
                }



    Friday, June 8, 2018 1:31 PM