作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 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/
我是一名优秀的程序员,十分优秀!