当前位置: 首页 > 编程语言 > C#

从C#调用非托管函数:我应该传递StringBuilder还是使用不安全代码?

时间:2023-04-10 21:36:11 C#

从C#调用非托管函数:我应该传递StringBuilder还是使用不安全代码?我有一个C#程序需要将char缓冲区传递给非托管函数。我发现了两种看起来可靠的方法,但我不确定应该选择哪一种。这是非托管函数的签名。extern"C"__declspec(dllexport)intgetNextResponse(char*buffer);第一个选项是将缓冲区定义为StringBuilder,如下所示。//在类级别...[DllImport("mydll.dll")]staticexternintgetNextResponse(StringBuilderbuffer);//在主要方法体中...StringBuildersb=newStringBuilder("",65536);intrc=getNextResponse(sb);这很简单,它有效,我想我基本上理解它为什么有效,因为StringBuilder在幕后有一个缓冲区,所以(我假设)互操作层只是将StringBuilder编组为char*。另一种选择是使用不安全代码。//在类级别...[DllImport("mydll.dll")]staticexternintgetNextResponse(byte*buffer);//单独的方法...privatestaticunsafeintrunGetNextResponse(byte[]buffer){fixed(byte*p=buffer){intrc=getNextResponse(p);返回rc;}}//在main方法体中...byte[]b=newbyte[65536];intrc=runGetNextResponse(b);该方法是更多的代码,但它也更明确地说明了正在发生的事情。这两种方法基本一样吗?有什么理由选择其中之一吗?我真的很喜欢使用StringBuilder版本。两者之间不会有太大区别,使用不安全代码并不是那么干净。在我看来,既然有一种方法可以使用核心库类来解决问题,那么使用没有明确(和必需)好处的不安全代码就是过早的优化。虽然首选使用StringBuilder,但有一个警告。例如,假设在您的getNextResponse方法中,您将指针存储到某个静态变量并在另一个方法中使用它:char*globalPointer;intgetNextResponse(char*buffer){globalPointer=buffer;返回0;}voidsomeOtherMethod(){printf("%sn",globalPointer);现在让我们看看管理端:varsb=newStringBuilder();sb.Append("你好世界");int结果=getNextResponse(sb);控制台.WriteLine(结果);一些其他方法();//kaboom:GC可能已经销毁了字符串生成器。不安全的方法保证你不会移动内存位置:byte[]buffer=Encoding.UTF8.GetBytes("HelloWorld");fixed(byte*p=buffer){intresult=getNextResponse(p);控制台.WriteLine(结果);一些其他方法();//工作正常,因为缓冲区地址固定在内存中}在这种情况下,不安全版本会工作得更好。虽然我无法确定权衡取舍,但我可以分享我自己的经验。我专门使用了StringBuilder方法,没有遇到任何问题。我喜欢它的简单代码和避免不安全性。这取决于编组的成本。如果您进行大量编组或编组数据很大,您可能希望重用缓冲区而不是每次都创建/销毁字符串构建器缓冲区。这取决于缓冲区中的数据实际上是什么。对于字符数据,请使用StringBuilder方法。如果是二进制数据,使用字节数组,但不要使用不安全的方法。虽然对“不安全”的夸大恐惧变得有点愚蠢,但没有理由不在有保证的情况下使用它,在这种情况下它是不必要的。用法:以上是C#学习教程:从C#调用非托管函数:我应该传递StringBuilder还是使用不安全代码?分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——//atclasslevel...[DllImport("mydll.dll")]staticexternintgetNextResponse([In,Out]byte[]buffer);//在main方法体中...byte[]buffer=newbyte[65536];intrc=getNextResponse(缓冲区);本文收集自网络,不代表立场,如有侵权请点右联系管理员删除。如需转载请注明出处: