Reputation: 617
I am trying to call native C++ code from C# project. To do that I followed the steps from this post.
But I get a stackoverflow exception when I create a huge array in the C++ file. Here is the code:
//CSharpTest.h
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSharpTest
{
class Program
{
static void Main(string[] args)
{
CpTest.Class1 instance = new CpTest.Class1();
Console.WriteLine(instance.DoSomething());
Console.ReadKey();
}
}
}
And the c++ file
// CpTest.h
#pragma once
using namespace System;
namespace CpTest {
public ref class Class1
{
public:
int DoSomething(){
int arr[640 * 480];
return 123;
}
// TODO: Add your methods for this class here.
};
}
The array declaration is causing the stackoverflow exception.
Earlier when I was running only the native C++ code I increased the stack size by increasing the 'Stack Reserve Size' from the project properties.
But for this case I don't know what to do.
Upvotes: 0
Views: 420
Reputation: 941218
int arr[640 * 480];
This array is stored on the stack in a C or C++ program. The equivalent of stackalloc
in a C# program. It requires 640 x 480 x 4 = 1,228,800 bytes of storage. That is too much, the default size of the stack is one megabyte. You overflowed the stack, the exception tells you about it.
This is a flaw in the native code, it should never rely on such big allocations to pan out at runtime and should use the free store instead. Operator new
in a C++ program, malloc
in a C program.
And preferrably array<int>^
in a C++/CLI program, that's a managed array that is stored on the GC heap, just like a C# array. You'd use pin_ptr<> to allow native code to party on the array.
Technically it is fixable in a C# project, you have to ask for a bigger stack for the startup thread, the one that the operating system creates and calls your Main() method. You automatically get one when you target x64, the default is 4 megabytes. But that's not generally an option if you have to interop with existing native code. You can run Editbin.exe with the /STACK option to patch the EXE file header and ask for a bigger stack. The post-build event in your C# project can look like this:
set path=%path%;$(DevEnvDir);$(DevEnvDir)..\..\vc\bin
editbin.exe /STACK:2097152 "$(TargetPath)"
Or run the native code from a thread you create yourself, use one of the Thread constructors that lets you specify the stack size.
Upvotes: 5