Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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# P/invoke System.executionEngineeException当数组作为ref/out传递时_C#_.net_Pinvoke_Dllimport - Fatal编程技术网

C# P/invoke System.executionEngineeException当数组作为ref/out传递时

C# P/invoke System.executionEngineeException当数组作为ref/out传递时,c#,.net,pinvoke,dllimport,C#,.net,Pinvoke,Dllimport,我在非托管dll函数swe_calc_ut上使用p/invoke int swe_calc_ut(double tjd_et, int ipl, int iflag, double *xx, char *serr) 参数xx是“用于存储结果的6个双精度数组”,参数serr是“用于返回错误消息的字符串” 我的c#代码如下 [DllImport("swedll32.dll")] private static extern int swe_calc_ut(double tjd_ut, int ip

我在非托管dll函数swe_calc_ut上使用p/invoke

int swe_calc_ut(double tjd_et, int ipl, int iflag, double *xx, char *serr)
参数xx是“用于存储结果的6个双精度数组”,参数serr是“用于返回错误消息的字符串”


我的c#代码如下

[DllImport("swedll32.dll")]
private static extern int swe_calc_ut(double tjd_ut, int ipl, int iflag, out double[] xx, out char[] serr);

double jul_day_UT=22000;
int p=3;
int iflag=64 * 1024;
double[] arr;
char[] serr;

int x = swe_calc_ut(jul_day_UT, p, iflag , out arr, out serr);

现在,当我执行swe_calc_ut函数时,我得到一个错误“抛出了类型为'System.executionEngineeException'的异常”。我是P/invoke新手,所以我可能犯了一个愚蠢的错误。我想它一定是数组,因为早些时候我无意中通过值传递它们时,没有得到错误。非常感谢您的帮助。

您不必在这里使用
out
ref
。事实上,他们两个都失去了。并将两个数组预先分配到C#中所需的大小。

这是C语言的惯例,通过传递指向数组第一个元素的指针来传递数组。因此,double[]已被封送为
double*
。当您使用out或ref关键字时,您告诉封送拆收器该函数返回指向新数组的指针,即
double**

该函数不创建新数组,它要求客户端传递一个足够大的数组来接收结果。因此,out和ref注释都不正确。serr参数应声明为StringBuilder btw


该函数非常危险,因为客户端无法说出它创建的数组有多大。特别是serr参数的问题。详细的错误消息很容易溢出数组的末尾,这将破坏垃圾收集堆。除了传递一个非常大的数组(即具有大容量的StringBuilder)并保持交叉之外,您什么也做不了。缓冲区溢出是恶意软件作者首选的攻击向量。不太可能在托管程序中被滥用,它只会用Fee来破坏应用程序。

参见您需要提供更多关于非托管函数的信息,更好的代码示例从C++调用这个函数。为什么xx被声明为双**?对于一维数组,double*就足够了。也许swe_calc_ut分配了这个数组?什么是数组大小?如何释放此阵列?serr参数也是如此。没有这些细节,就不可能写出正确的PInvoke调用。