Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6718209
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T08:56:32+00:00 2026-05-26T08:56:32+00:00

I need to drop into C++ from C# and bring back a 2D array

  • 0

I need to drop into C++ from C# and bring back a 2D array of a struct. I have everything set up, and if I attach a debugger everything appears to be going right, except my 2D array isn’t marshaling appropriately. If I load it with values before calling the native method, and then view the array from the native side I get lots of “invalid” pointers in my watch window in VS. Then the C++ code goes ahead and loads up the array with values just fine, but during marshaling back to C# I get a memory access violation.

I’d rather not do this as a 1d array.

Here’s my C++ struct and method definition:

struct DoubleStringStruct
{
    BSTR Value;
    BSTR NumberFormat;
};

HRESULT WINAPI NativeArrayHandler(LONG rMax, LONG cMax, DoubleStringStruct** values)
{
    for(LONG rn=1; rn <= rMax; rn++)
    {
         for (LONG cn = 1; cn <= cMax; cn++)
         {
               DoubleStringStruct s;
               s.Value = _wcsdup(L"Test");
               s.NumberFormat = _wcsdup(L"Test");
               values[rn][cn] = s;
         }
     }

     return S_OK;
}

and my C# code:

[StructLayout(LayoutKind.Sequential)]
public struct DoubleStringStruct
{
    [MarshalAs(UnmanagedType.BStr)]
    public string value;
    [MarshalAs(UnmanagedType.BStr)]
    public string numberFormat;
}


[System.Runtime.InteropServices.DllImport(c_dllName)]
public static extern void NativeArrayHandler(int hMax, int cMax, DoubleStringStruct[,] args);

public void sometMethod()
{
     DoubleStringStruct[,] someDSS= new DoubleStringStruct[4,3];

     NativeArrayHandler(4, 3, someDSS);
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T08:56:32+00:00Added an answer on May 26, 2026 at 8:56 am

    Hrm, well Hans Passant helped me get to this answer, so props to him.

    There were three problems with my code

    1) _wcsdup returns a WCHAR_T * but my struct contains BSTR, which is really a WHCAR *

    2) The marshaller doesn’t create a 2d array for us, rather a 1d array which has to be indexed in a funny way. Note below.

    3) I need to make sure that any memory I create in the native code gets cleaned up, either by myself or by the Marshaller. For example, just about all the native memory I used in the question never gets freed, resulting in a huge memory leak. Currently when the native code returns to managed code I lose all my native pointers to memory that needs to be freed. I solved this passing a callback when making the call into native code. The native code does its work, makes a functional call back to managed, which returns, and allows the native code to do housekeeping. An easy way to do this housekeeping was to use the power of CComSafeArray’s and CComBSTR’s, which will manage themselves. (I know I should be able to simply pass the CComSafeArray’s to the marshaller and they’ll get cleaned up in the .net code, but I haven’t been able to figure out how to do that).

    Unfortunately, the marshaling of a 2D array requires custom marshaling, which results in too many COM calls for my tastes. Consequently, I marshalled a 1D array and indexed it accordingly per Hans Passant’s suggestion. Futhermore, due to time constraints I created an array for each string in DoubleStringStruct, though I could have made DoubleStringStruct COMVisible and then I could have marshalled it in a single array.

    Here’s the final code I ended up with.

    extern "C" __declspec(dllexport)
    HRESULT WINAPI NativeArrayHandler(LONG rMax, LONG cMax, void (WINAPI*callback)(SAFEARRAY*, SAFEARRAY*))
    {
        CComSafeArray<BSTR> valuesArr = CComSafeArray<BSTR>(rMax*cMax);
        CComSafeArray<BSTR> formatsArr = CComSafeArray<BSTR>(rMax*cMax);
    
    
        for(LONG rn=0; rn < rMax; rn++)
        {
             for (LONG cn = 0; cn < cMax; cn++)
             {
                   int index = cMax * rn + cn;
                   valuesArr[index] = CComBSTR(L"Test");
                   formatsArr[index] = CComBSTR(L"Test");
             }
         }
    
        callback(valuesArr, formatsArr);
    
        valuesArr.Destroy();
        formatsArr.Destroy();
    
        return S_OK;
    }
    

    And the C#

    static void Main(string[] args)
    {
            NativeArrayHandler(4, 3, (v, f) => { printArrays(4, 3, v, f); });
    }
    
    
    public static void printArrays(int rmax, int cmax, string[] valuesArr, string[] formatsArr)
    {
         // can print the arrays in managed code here
    }
    
    
        [System.Runtime.InteropServices.DllImport("dll location")]
        public static extern void NativeArrayHandler(int hMax, int cMax, NativeArrayHandlerCallback cb);
    
    
        public delegate void NativeArrayHandlerCallback(
            [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] string[] arr1,
            [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] string[] arr2);
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

i need to drag from grlRicProd to drop into grlInsOrd grlIRicProd: ..... id: 'grlRicProd',
I need to take an existing winforms application and drop into an event tracing
I have a drop down list that has options that need to be passed
On a JSTL/JSP page, I have a java.util.Date object from my application. I need
I have a backup like this: Select * Into BACKUP From ORIGINAL Then I
I'm making a forum software, and I need to put an array into a
Im runing mySQL in a server where i need to drop tons of databases
I am modifying a SQL table through C# code and I need to drop
Need to take a SELECT drop down list options and find if any of
i need to be able to drag and drop my picturebox with an image

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.