gpt4 book ai didi

c# - 从 C 返回时崩溃 : Why (of course)?

转载 作者:行者123 更新时间:2023-11-30 21:06:32 24 4
gpt4 key购买 nike

在 C# 中,我填充了一个二进制缓冲区(1.5 到 2 kB),我在 C DLL 中引用了该缓冲区。一切都很顺利(逐步执行 C 是这么说的),直到我必须返回到 C#。在最后一刻,程序崩溃了(没有抛出异常,只是崩溃:“停止工作”)。Cr 是 DLL 中的 C 例程。我在 Visual Studio Community 2017 工作。早些时候,我通过 C 语言中的字符串和 sscanf_s 传递数据,效果很好,但希望加快速度(并在此过程中学习不同的东西)。缓冲区包含各种浮点型、整数型和 double 型,它们在 C 端被正确拾取(步进是这样说的)。这是第一段 C# 代码:

    double[,] MemberEndforces = new double[mbCount, 12];
double[,] Deflection = new double[mbCount + 1, 6];
//double[] Reactions = new double[6];

unsafe
{
using (BinaryWriter binWriter = new BinaryWriter(new MemoryStream()))
{

BuildExportBuffer(binWriter);
var buffer = ((MemoryStream)binWriter.BaseStream).GetBuffer();
info = NativeMethods.Cr(
ref buffer, NrOfMod, Eigenfreqs, ref error,
ref rms_resid, MemberEndforces, Deflection);
} // end using
if (info != 0)
throw new MyException(string.Format(ErrorMessages.SomeError, info));
bool converged = error < tolerance;

...
} // end unsafe

下面是接收 C 例程的头部。仅在最后一个大括号处,并返回到 C#,才会发生崩溃。无论有或没有 safe{} block ,它都会这样做。

extern "C"
{
char ** buffer;
//char * next_token;

__declspec(dllexport) int __cdecl Cr(
char **_buffer,
int n,
float * eigenFreq,
double * error,
double * rms_resid,
double * endforces,
double * deflection
)
{ buffer = _buffer;
...
// read stuff from buffer and process it...
return ExitCode;

}

这是 DLL 导入:

[DllImport(@"Cr.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Cr", 
CharSet = CharSet.Ansi, BestFitMapping =false,ThrowOnUnmappableChar =true)]


public static extern int Cr([In] ref byte[] buffer,
[In] int n,
float[] eigenfreq,
ref double error,
ref double rms_resid,
double[,] force,
double[,] defl);

所以:为什么?我做错了什么?如果 C 部分有问题,它会早于最后一个花括号显示,不是吗? C 代码的最后一部分做了很多释放 malloc 的 block (不是缓冲区!)。

最佳答案

根据this post在 MSDN 上,调用外部函数时不会对多维数组进行编码(marshal),因此您必须将数组转换为一维数组。

据我所知,这些数组是输出缓冲区,因此为了调用,您可以这样做:

double[] MemberEndforces = new double[mbCount * 12];
double[] Deflection = new double[(mbCount + 1) * 6];

//...

info = NativeMethods.Cr(
ref buffer, NrOfMod, Eigenfreqs, ref error,
ref rms_resid, MemberEndforces, Deflection);

然后,在调用函数后,您需要将这些数组转换为多维数组:

double[,] mMemberEndforces = new double[mbCount, 12];
double[,] mDeflection = new double[mbCount + 1, 6];

for(int x = 0; x < mbCount; x++)
{
for(int y = 0; y < 12; y++)
mMemberEndforces[x,y] = MemberEndforces[x * 12 + y];
}

for(int x = 0; x < mbCount + 1; x++)
{
for(int y = 0; y < 6; y++)
mDeflection[x,y] = Deflection[x * 6 + y];
}

关于c# - 从 C 返回时崩溃 : Why (of course)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47998864/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com