Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;从C++;控制台应用程序正常工作,从C#调用控制台应用程序时堆栈溢出_C#_C++_Interop_Stack Overflow - Fatal编程技术网

C++;从C++;控制台应用程序正常工作,从C#调用控制台应用程序时堆栈溢出

C++;从C++;控制台应用程序正常工作,从C#调用控制台应用程序时堆栈溢出,c#,c++,interop,stack-overflow,C#,C++,Interop,Stack Overflow,我收到了一些C/C++代码,可以在另一个项目中使用。我把它放到一个DLL中,然后从C++测试线束调用DLL。它工作得很好,并且与代码只是一个函数调用时的结果相匹配 然而,我随后试图让DLL从C#应用程序运行。我转换了测试线束,并进行了DLL调用,但收到堆栈溢出异常 在C++中,我添加了: #include "proxy_rec_02.h" #pragma comment(lib,"proxy_rec_02.lib") 并调用如下函数: proxy_rec_main(simtime

我收到了一些C/C++代码,可以在另一个项目中使用。我把它放到一个DLL中,然后从C++测试线束调用DLL。它工作得很好,并且与代码只是一个函数调用时的结果相匹配

然而,我随后试图让DLL从C#应用程序运行。我转换了测试线束,并进行了DLL调用,但收到堆栈溢出异常

在C++中,我添加了:

 #include "proxy_rec_02.h"  
 #pragma comment(lib,"proxy_rec_02.lib")  
并调用如下函数:

 proxy_rec_main(simtime,mx$gl,mz$gl,ry,start_dig,blytarg_on,blytarg,spread_on,last_call,outputs);
proxy_rec_main(simtime,mxSgl,mzSgl,ry,start_dig,blytarg_on,blytarg,spread_on,last_call,ref outputs);
其中标题包含:

void DLL_EXPORT proxy_rec_main(double simtime, double mx$gl, double mz$gl, double ry, int start_dig,  
                               int blytarg_on, double blytarg, int spread_on, int last_call, double *outputs);
在C#中,我使用:

using System.Runtime.InteropServices;

使用如下函数调用:

 proxy_rec_main(simtime,mx$gl,mz$gl,ry,start_dig,blytarg_on,blytarg,spread_on,last_call,outputs);
proxy_rec_main(simtime,mxSgl,mzSgl,ry,start_dig,blytarg_on,blytarg,spread_on,last_call,ref outputs);
DLL函数在for循环中被多次调用。C++代码运行良好。C代码抛出堆栈溢出错误。我在proxy_rec_main函数中添加了一些debug statemaints,它似乎在函数返回之前命中了每条语句。但它似乎在函数返回时抛出错误。欢迎有任何见解


谢谢。

ref双数组似乎有问题, 向其中添加[Marshallas]并传递IntPtr,而不是双数组

.NET数组不是指针,因为它们在C++中。

将该c#方法标记为private, wrap with public方法,该方法使用Marshal.Copy将返回的指针传输到.net数组

在.net中分配时传输阵列的示例:

[DllImport(EntryPoint="ExternalMethod"]
private static void ExternalMethodInvoke(
    [MarshalAs(UnmanagedType.SysInt), In] IntPtr);

public void ManagedWrapper(ref double[] array)
{
    IntPtr unmanagedMem = Marshal.AllocHGlobal(1000);
    Marshal.Copy(array, unmanagedMem, 0, 1000);
    ExternalMethodInvoke(unmanagedMem); // use try finally for freeing
    Marshal.Copy(unmanagedMem, array, 1, 1000);
    Marshal.FreeHGlobal(unmanagedMem);
}
在本机中分配时传输阵列的示例:

[DllImport(EntryPoint="ExternalMethod"]
private static void ExternalMethodInvoke(
    [MarshalAs(UnmanagedType.SysInt), Out] out IntPtr);

[DllImport(EntryPoint="ExternalDeleteArray"]
private static void ExternalDeleteArrayInvoke(
    [MarshalAs(UnmanagedType.SysInt), Out] out IntPtr);

public void ManagedWrapper(ref double[] array)
{
    IntPtr unmanagedMem;
    ExternalMethodInvoke(out unmanagedMem); // use try finally for freeing
    Marshal.Copy(unmanagedMem, array, 1, 1000);
    ExternalDeleteArrayInvoke(unmanagedMem);
}
如果c#端分配数组,不要忘记在c#中分配和取消分配。 (使用封送员(de)分配h全局方法。)


<>在C++中分配,调用C++方法来释放。

从[dLimPurt]声明中删除CalueCueNe结属性。没有迹象表明您在C声明中使用了_stdcall,因此可能需要调用Convention.Cdecl。这确实会导致SO,堆栈不会被清理

调试+Windows+寄存器,并在调用前后观察ESP寄存器的值,该值应相同。如果禁用了PinVokesTack托管调试器警告,请确保将其重新启用。忽视这个警告不是一个好主意


并调试本机代码,验证传递的参数值。参数太多了,其中一个参数的一个错误声明就足以让人大吃一惊。

假设粘合代码是正确的,那么可能只是DLL函数占用了大量堆栈。我自己也遇到了类似的情况,结果发现在C++堆栈上分配了一些非常大的对象。当从本机代码调用时,在调用之前只使用了一点点堆栈,因此堆栈上有足够的剩余空间。当从托管代码调用时,大量堆栈已经被占用,所以没有足够的空间。如果你看到了导致溢出的C++函数,你可能会发现它试图在堆栈上放置一个大对象。

所以我不太确定如何进行这些改变。我已将该数组封送到非托管数组,并具有一个IntPtr。但是我不知道如何改变界面来接受它,所以我不知道如何进行这些改变。我已将该数组封送到非托管数组,并具有一个IntPtr。但我不知道如何改变接口来接受它。int size=Marshal.SizeOf(outputs[0])*outputs.Length;IntPtr pnt=封送。AllocHGlobal(大小);封送处理副本(输出、0、pnt、输入、长度);然后函数调用应该发生。抱歉,编辑时间用完了。所以我仍然无法获取它。这是我第一次尝试interop。那么,我是否要将DLLImoprt从ref double[]输出更改为[marshallas(UnmanagedType.SysInt)]ref double[]输出,然后将我创建的IntPtr传递给函数?对不起,我没有看到您编辑了我的原始帖子。但我并没有看到任何变化(在回答时),我只是在问题中添加了标记。这通常是类成员方法的问题。