*** 关于从 C# 调用本机 C++
Posted
技术标签:
【中文标题】*** 关于从 C# 调用本机 C++【英文标题】:*** on calling native c++ from c# 【发布时间】:2015-01-29 13:59:28 【问题描述】:我正在尝试从 C# 项目调用本机 C++ 代码。为此,我按照this post 中的步骤操作。
但是当我在 C++ 文件中创建一个巨大的数组时,我得到了一个 *** 异常。代码如下:
//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();
还有 c++ 文件
// 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.
;
数组声明导致***异常。
早些时候,当我只运行本机 C++ 代码时,我通过增加项目属性中的“堆栈保留大小”来增加堆栈大小。
但对于这种情况,我不知道该怎么办。
【问题讨论】:
必须在栈上分配数组吗? 不一定。但我不知道该怎么做。 您的“本机 C++”实际上是 C++/CLI,即 Microsoft 针对 .Net 互操作的 C++ 扩展。我已经删除了 C++ 标签并添加了 c++-cli。 在堆上分配数组,或者最好使用std::vector
。在堆栈上分配如此大的数组通常不是一个好主意。
@odyss-jii 感谢您的帮助
【参考方案1】:
int arr[640 * 480];
此数组存储在 C 或 C++ 程序的堆栈中。相当于 C# 程序中的 stackalloc
。它需要 640 x 480 x 4 = 1,228,800 字节的存储空间。太多了,堆栈的默认大小是 1 兆字节。你溢出了堆栈,异常告诉你。
这是本机代码中的一个缺陷,它不应该依赖如此大的分配来在运行时实现,而应该使用免费存储。运算符 new
在 C++ 程序中,malloc
在 C 程序中。
在 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)"
或从您自己创建的线程运行本机代码,使用可让您指定堆栈大小的Thread constructors 之一。
【讨论】:
以上是关于*** 关于从 C# 调用本机 C++的主要内容,如果未能解决你的问题,请参考以下文章
从 c# 代码调用带有 void *parameter 的本机 c++ 函数
通过 Marshal.GetFunctionPointerForDelegate 从本机 (C++) 线程调用托管函数 (C#)
从本机 C++ 调用 C#,而不使用 /clr 或 COM?