2017-03-28 17 views
5

私はマーシャルにしようとしているunmaged COMオブジェクトのメソッドがあります。.NETでLPSTR **をマーシャリングする方法は?

STDMETHOD(SomeMethod)(LPSTR** items, INT* numOfItems) = 0; 

をしかし、私はLPSTR **項目をマーシャリングする正しい方法を把握することはできません。それはアイテムのリストであるはずです。しかし、このような何かをしようとした場合:

[PreserveSig] 
int SomeMethod([MarshalAs(UnmanagedType.LPStr)]ref StringBuilder items, ref uint numOfItems); 

すると、私は非常に最初の項目と他には何の非常に最初の文字を取得します。

LPSTR **変数を正しくマーシャリングできますか?

+1

これは、より多くの 'StringBuilderの[]'のようにする必要があります。このパラメータは手動で整列化できます(例:[この質問](http://stackoverflow.com/q/16857034/1997232))。 – Sinatr

+0

@Sinatr、私はStringBuilder []を使ってみましたが、この場合、私はこのエラーが出ます: "マネージドデバッグアシスタント 'ContextSwitchDeadlock'が発生しました。あなたが提供したリンクを見てみましょう。 – user208478

+0

マーシャリングの方向は何ですか? In、Out、Both? – arbiter

答えて

0

私は今、それを確認することはできませんが、署名は次のようになります。もちろん

[PreserveSig] 
int SomeMethod(
    [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 1)] out string[] items, 
    out int numOfItems); 

、それは助けにはならないで、(Sinatrが示唆したように)あなたはいつもMarshalクラスを経由して手動マーシャリングを実行することができます。

0

これを試してみてください:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace ConsoleApplication49 
{ 
    class Program 
    { 
     [StructLayout(LayoutKind.Sequential)] 
     public struct UnmanagedStruct 
     { 
      [MarshalAs(UnmanagedType.ByValArray)] 
      public IntPtr[] listOfStrings; 
     } 


     static void Main(string[] args) 
     { 
      UnmanagedStruct uStruct = new UnmanagedStruct(); 
      IntPtr strPtr = uStruct.listOfStrings[0]; 

      List<string> data = new List<string>(); 
      while (strPtr != IntPtr.Zero) 
      { 
       string readStr = Marshal.PtrToStringAnsi(strPtr); 
       data.Add(readStr); 
       strPtr += readStr.Length; //I think it should be Length + 1 to include '\0' 
      } 
     } 
    } 
} 
関連する問題