Stackoverflow调用本机c ++从c# [英] Stackoverflow on calling native c++ from c#
问题描述
我试图从C#项目调用本地C ++代码。为此,我按照此帖的步骤操作。 / p>
但是当我在C ++文件中创建一个巨大的数组时,我得到了一个stackoverflow异常。这里是代码:
// CSharpTest.h
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
命名空间CSharpTest
{
类程序
{
static void Main(string [] args)
{
CpTest。 Class1 instance = new CpTest.Class1();
Console.WriteLine(instance.DoSomething());
Console.ReadKey();
}
}
}
p>
// CpTest.h
#pragma once
using namespace System;
命名空间CpTest {
public ref class Class1
{
public:
int DoSomething(){
int arr [ 640 * 480];
return 123;
}
// TODO:在这里为这个类添加方法。
};
}
数组声明引起stackoverflow异常。
早期当我只运行本地C ++代码时,通过增加项目属性中的堆栈保留大小来增加堆栈大小。
但对于这种情况,我不知道该怎么办。
int arr [640 * 480];
此数组以C或C ++程序存储在堆栈中。在C#程序中相当于 stackalloc
。它需要640 x 480 x 4 = 1,228,800字节的存储空间。这太多了,堆栈的默认大小是一兆字节。
这是本地代码中的缺陷,它不应该依赖这么大的分配在运行时进行平移,应该使用免费商店。在C程序中的操作符 new
,在C程序中 malloc
。
并且最好是C ++ / CLI程序中的 array< int> ^
,这是一个存储在GC堆上的托管数组,就像C#数组一样。你可以使用pin_ptr<>允许本地代码在数组上进行聚会。
从技术上说,它在C#项目中是可修复的,启动线程,操作系统创建并调用Main()方法的线程。当您定位x64时,自动获取一个,默认值为4兆字节。但是,如果你必须与现有的本地代码交互,这通常不是一个选项。你可以使用/ STACK选项运行Editbin.exe来修复EXE文件头,并要求更大的堆栈。在你的C#项目中的后构建事件可以看起来像这样:
set path =%path%; $(DevEnvDir); $(DevEnvDir).. \..\vc\bin
editbin.exe / STACK:2097152$(TargetPath)
或者从你自己创建的线程中运行本地代码,使用线程构造函数,允许您指定堆栈大小。
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.
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.
这篇关于Stackoverflow调用本机c ++从c#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!