【问题标题】:How to declare and use fixed size char buffer in C# struct如何在 C# struct 中声明和使用固定大小的字符缓冲区
【发布时间】:2016-06-15 05:15:36
【问题描述】:

我有以下结构声明:

[StructLayout(LayoutKind.Sequential)]
public struct MyDLLInput
{
    ...
    public fixed char PathtoData[256];
};

PathtoData 按原样显示错误:

"Pointers and fixed-size buffers may only be used in an unsafe context."

MyDLLInput 被传递给 C++ DLL:

public class MyDLL
{
    [DllImport("MyDLL.dll",
        EntryPoint = "?Unit@@YA?AUOutput@@UInput@@@Z",
        CallingConvention = CallingConvention.Cdecl)]
    public static extern MyDLLOutput Unit(MyDLLInput UnitInput);
}

MyDLL.h 将成员定义为:

char PathtoData[256];

如何在我的 C# 代码中正确地进行成员声明?

【问题讨论】:

  • 你能用成员 PathToData 展示完整的 C++ 类吗?另外为什么不使用Exporting C++ Functions for Use 而不是像 "?Unit@@YA?AUOutput@@UInput@@@Z" 这样的错位函数名称?
  • @ArtavazdBalayan C++ DLL 是由另一位开发人员提供给我的。我没有源代码,虽然我可以得到它。我不太了解 C++,无法按照您的建议进行操作。通过 Dependency Walker 向我提供了损坏的名称。
  • @ArtavazdBalayan 但我会将您的链接转发给该 C++ DLL 的开发人员。错位的名字并没有真正困扰我。一旦它到位,它就看不见了,但我确实喜欢你的建议。
  • 我为什么要询问 C++ 代码,因为我不确定您在这里需要不安全。这只是 P/Invoke。

标签: c# c++ struct


【解决方案1】:

正如它所说:

指针和固定大小的缓冲区只能在不安全的上下文中使用。

所以为了像这样使用固定大小的字符缓冲区,您需要将unsafe 添加到您的结构中:

public unsafe struct MyDLLInput
{
   ...
   public fixed char PathtoData[256];
};

您还需要允许这样的不安全编译:

  1. 右键单击您的项目。
  2. 选择“属性”。
  3. 切换到“构建”选项卡。
  4. 勾选“允许不安全代码”

根据MSDN - Unsafe Code and Pointers (C# Programming Guide)

在公共语言运行时 (CLR) 中,不安全的代码被称为无法验证的代码。 C# 中的不安全代码不一定是危险的;它只是 CLR 无法验证其安全性的代码。因此,如果 CLR 位于完全受信任的程序集中,则 CLR 只会执行不安全的代码。如果您使用不安全的代码,您有责任确保您的代码不会引入安全风险或指针错误。

有关安全和不安全代码的更多信息和比较,您还可以查看 Safe and Unsafe Code 在 MSDN。

【讨论】:

  • 我从未使用过unsafe。您的示例处理了所有错误。对于unsafe 如何影响应用程序的其余部分,是否有一个简单的解释?或者此设置是否只影响标有unsafe 属性的代码?
  • 另请注意,C++ 中的 char 通常是 8 位(取决于平台),但在 C# 中是 16 位(如果在 Windows 上,则在 C++ 中为 wchar_t)。简而言之:将类型更改为字节并处理编码转换。
  • @rwkiii,我更新了答案,但是您应该考虑编码转换,因为 Adriano 提到的是他的评论。
  • @hsh 是的,我已将其设置为字节。谢谢你们俩。这一切都非常有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
相关资源
最近更新 更多