none
CLR Hosting: passing a CLR float[][] to unmanaged code. Unknown error 0x80131533 RRS feed

  • Question

  • Hi,

    I am trying to retrieve a CLR nested array, in a CLR hosting context, and marshall it to a representation in the R statistical software.

    public static float[][] CreateTestNestedArray()

    In debug mode, the array is created and returned. However the invoking by the C++ layer fails with an "Unknown error 0x80131533". First question: are nested arrays not particular variant types, and if so why are they not treated as an array of plain objects (VT_ARRAY | VT_UNKNOWN or something like that). Note that the C++ layer works fine on non-nested arrays of various types.

        HRESULT hr = spType->InvokeMember_3(*bstrStaticMethodNamePtr, static_cast<BindingFlags>(
            BindingFlags_InvokeMethod | BindingFlags_Static | BindingFlags_Public), 
            NULL, vtEmpty, psaStaticMethodArgs, vtResult);
        if (FAILED(hr))	{
            error("Static method call failed with message: %s\n", getComErrorMsg(hr));
    

    Second step, I then try to wrap the array in a C# object NumericMatrix (rdotnet.codeplex.com). Same thing, all good stepping through the C# code, but InvokeMember_3 fails with a marginally better message "The parameter is incorrect", i.e. hresult code E_INVALIDARG and a VT_EMPTY returned value. That NumericMatrix object is deisgned for managed/unmanaged interop, inheriting from SafeHandle. I would expect InvokeMember_3 to get a VT_DISPATCH or VT_UNKNOWN.

    	[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    	public class NumericMatrix : Matrix<double>
    	public abstract class Matrix<T> : SymbolicExpression
    	public class SymbolicExpression : SafeHandle
    

    Any insight/suggestion/workaround will be appreciated.

    Thursday, November 22, 2012 9:12 AM

Answers

  • Hi,

    You can take a look this article sample for marshal array from managed to unmanaged: http://msdn.microsoft.com/en-us/library/9b1fy41s.aspx

    // PassArray1.cpp
    // compile with: /clr
    #ifndef _CRT_RAND_S
    #define _CRT_RAND_S
    #endif
    
    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    
    using namespace System;
    
    #pragma unmanaged
    
    void TakesAnArray(int* a, int c) {
       cout << "(unmanaged) array received:\n";
       for (int i=0; i<c; i++)
          cout << "a[" << i << "] = " << a[i] << "\n";
    
       unsigned int number;
       errno_t err;
    
       cout << "(unmanaged) modifying array contents...\n";
       for (int i=0; i<c; i++) {
          err = rand_s( &number );
          if ( err == 0 )
             a[i] = number % 100;
       }
    }
    
    #pragma managed
    
    int main() {
       array<int>^ nums = gcnew array<int>(5);
    
       nums[0] = 0;
       nums[1] = 1;
       nums[2] = 2;
       nums[3] = 3;
       nums[4] = 4;
    
       Console::WriteLine("(managed) array created:");
       for (int i=0; i<5; i++)
          Console::WriteLine("a[{0}] = {1}", i, nums[i]);
    
       pin_ptr<int> pp = &nums[0];
       TakesAnArray(pp, 5);
    
       Console::WriteLine("(managed) contents:");
       for (int i=0; i<5; i++)
          Console::WriteLine("a[{0}] = {1}", i, nums[i]);
    }

    This one also can provide some insight about passing arrays to COM from managed code: http://msdn.microsoft.com/en-us/library/z6cfh6e6%28v=vs.110%29.aspx


    Regards,
    Christian HL
    Microsoft Online Community Support


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Monday, November 26, 2012 9:20 AM

All replies

  • Hi Jm,

    Welcome to the MSDN Forum.

    I am trying to involve some other one into this case. Wait it patiently, please.

    Thank you.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, November 23, 2012 10:24 AM
    Moderator
  • I found (rather, rediscovered) how to get the second solution working. For information:

    The NumericMatrix object is a SafeHandle, and returning the IntPtr numericMatrix.GetDangerousHandle() to the unmanaged code layer is what works. There is probably some deep-seated code in the CLR hosting or CLR itself checking for objects that are SafeHandle.

    However, I am still curious to get opinions on what to do with float[][] arrays if I were not to use this NumericMatrix wrapper.

    Regards.

    Saturday, November 24, 2012 7:27 AM
  • Hi,

    You can take a look this article sample for marshal array from managed to unmanaged: http://msdn.microsoft.com/en-us/library/9b1fy41s.aspx

    // PassArray1.cpp
    // compile with: /clr
    #ifndef _CRT_RAND_S
    #define _CRT_RAND_S
    #endif
    
    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    
    using namespace System;
    
    #pragma unmanaged
    
    void TakesAnArray(int* a, int c) {
       cout << "(unmanaged) array received:\n";
       for (int i=0; i<c; i++)
          cout << "a[" << i << "] = " << a[i] << "\n";
    
       unsigned int number;
       errno_t err;
    
       cout << "(unmanaged) modifying array contents...\n";
       for (int i=0; i<c; i++) {
          err = rand_s( &number );
          if ( err == 0 )
             a[i] = number % 100;
       }
    }
    
    #pragma managed
    
    int main() {
       array<int>^ nums = gcnew array<int>(5);
    
       nums[0] = 0;
       nums[1] = 1;
       nums[2] = 2;
       nums[3] = 3;
       nums[4] = 4;
    
       Console::WriteLine("(managed) array created:");
       for (int i=0; i<5; i++)
          Console::WriteLine("a[{0}] = {1}", i, nums[i]);
    
       pin_ptr<int> pp = &nums[0];
       TakesAnArray(pp, 5);
    
       Console::WriteLine("(managed) contents:");
       for (int i=0; i<5; i++)
          Console::WriteLine("a[{0}] = {1}", i, nums[i]);
    }

    This one also can provide some insight about passing arrays to COM from managed code: http://msdn.microsoft.com/en-us/library/z6cfh6e6%28v=vs.110%29.aspx


    Regards,
    Christian HL
    Microsoft Online Community Support


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Monday, November 26, 2012 9:20 AM