zoukankan      html  css  js  c++  java
  • 刚才遇到了关于C#使用外部DLL函数上的char*的问题。

    有个网友在群中说:“问一个问题,vc写的dll返回值为char *,c#中如何定义,我定义了string,要出错的。”
    有个网友建议他用unsafe,而后来他说他解决了,他的代码如下:

      [ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi ) ]
       
    public struct
      KeyBuf
      
    {
                [ MarshalAs( UnmanagedType.ByValTStr, SizeConst
    =256
     )] 
                
    public string
     c;
      }
     

    他说这样就可以解决了,但后来,他又问,为什么非要用结构?
    我也不清楚,希望有朋友可以指出一下。

    后来,我试了一下:
      [MarshalAs(UnmanagedType.LPArray)] 
      
    public byte[] c;

    但有一些问题,后来,用了:
    [MarshalAs(UnmanagedType.LPArray)] 
    public byte[] c=new byte[256];

    为byte弄了一个缓冲区,成功了。

    但又遇到一个问题,用Conver不能直接转换数符为string,所以改用了System.Text.Encoding才解决了问题。

    经查MSDN资料发现UnmanagedType 枚举描述:
    ByValTStr
    用于在结构中出现的内联定长字符数组。与 ByValTStr 一起使用的字符类型由应用于包含结构的
    System.Runtime.InteropServices.StructLayoutAttributeSystem.Runtime.InteropServices.CharSet 参数确定。应始终使用 MarshalAsAttribute.SizeConst 字段来指示数组的大小。 .NET Framework 的 ByValTStr 类型的行为类似于结构中的 C 样式、固定大小的字符串(例如,char s[5])。托管代码中的行为与 Microsoft Visual Basic 6.0 中的行为不同,后者不是空终止(例如,MyString As String * 5)。

    LPArray

    指向 C 样式数组的第一个元素的指针。当从托管到非托管进行封送处理时,该数组的长度由托管数组的长度确定。当从非托管到托管进行封送处理时,将根据 MarshalAsAttribute.SizeConstMarshalAsAttribute.SizeParamIndex 字段确定该数组的长度,当需要区分字符串类型时,还可以后跟数组中元素的非托管类型。

    也就是说ByValStr仅适合用于定长的字符串,而LPArray才用于不定长的字串。
    看见国外有用StringBulider的解决方案,是String到Char *的映射的,还没试过行不行,具体可以看这里
  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/William_Fire/p/28950.html
Copyright © 2011-2022 走看看