数组大小超过寻址限制(C#与C++)

本文关键字:C++ 寻址 数组 | 更新日期: 2023-09-27 18:21:07

我有一个C#程序,它管理庞大的Complex阵列(大于2GB)。此在x64中编译的程序使用App.config:中的gcAllowVeryLargeObjects=true子句

<configuration>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>

它需要使用第三方dll,但当它将这些huges数组传递给这个外部函数时,编组似乎失败了。

这是异常"阵列大小超过地址限制"

这似乎是一个VS CLR问题,因为我做了这个例子来演示它

class Program
{
    static void Main(string[] args)
    {
        MyWrapper.MyTest();
    }
}
[SuppressUnmanagedCodeSecurity]
public class MyWrapper    
{

    private MyWrapper()
    {
    }
    internal static int CS_foo(
    [In] Complex[,] A // text to prepend to converted integer
     )
    {
         Complex B_complex= new Complex(0, 0);
        for (int i = 0; i< 10; i++)
        {
            B_complex = A[0, i];
            Console.WriteLine(string.Format(" from C# A({0})'t{1}'ti{2}", i, B_complex.Real, B_complex.Imaginary));
        }
        return 0;
    }
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    [DllImport("DLL1.dll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
    internal static extern int C_foo(     
      [In] Complex[,] A// text to prepend to converted integer
     );

    public static void MyTest()
    {
        Complex[,]A = new Complex[12000, 12000];
        A[0, 0] = new Complex(0.1, -0.1);
        A[0, 1] = new Complex(11.0, 0.1);
        A[0, 5] = new Complex (55, -0.5);
        A[0, 9] = new Complex (99.0, 0.9);
        MyWrapper.CS_foo(A);
        MyWrapper.C_foo(A); //Here Fails!!            
    }
}

C++DLL代码:

#include "stdafx.h"
#include "stdio.h"

#ifndef Complex16
typedef
struct Complex16 {
    double real;
    double imag;
} Complex16;
#endif
extern "C" int __declspec(dllexport)  C_foo(
    Complex16* A 
    )
{
    Complex16  B;
    for (int i = 0; i < 10; i++)
    {       
    B.real = A[i].real;
    B.imag = A[i].imag;
    printf("   hello from C A(%d)=( %f %f ) 'n ", i, B.real, B.imag);
    }
    return 0;
}

如果您更改数组大小(例如1200x1200),则示例有效!你知道如何解决这个问题吗?

他友

数组大小超过寻址限制(C#与C++)

可以在此处找到解决方案:https://social.msdn.microsoft.com/Forums/vstudio/en-US/b02c61ab-8be1-4ed1-9752-9fa24211d78a/c-vs-c-array-size-exceeds-adressing-limitation?forum=csharpgeneral

简而言之:

默认封送处理不喜欢这样大的数组。固定数组并将指向其第一个元素的指针传递给本机函数:

using System.Numerics;
using System.Runtime.InteropServices;
public unsafe class MyWrapper
{
    static void Main(string[] args)
    {
        Complex[,] A = new Complex[12000, 12000];
        A[0, 0] = new Complex(0.1, -0.1);
        A[0, 1] = new Complex(11.0, 0.1);
        A[0, 5] = new Complex(55, -0.5);
        A[0, 9] = new Complex(99.0, 0.9);
        fixed (Complex* p = &A[0, 0])
            C_foo(p);
    }
    [DllImport("DLL1.dll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
    internal static extern int C_foo(Complex* A);