2017-03-28 34 views
5

Ben Marshall'a çalışıyorum unmaged COM nesnesi bir yöntemi vardır:.NET'te LPSTR ** nasıl sıralanır?

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

Ama ** öğeleri LPSTR dışarı sıralamakta doğru şekilde anlamaya olamaz. Öğelerin bir listesi olması gerekiyordu. Böyle bir şey yapmak için denemek Ancak eğer:

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

Sadece ilk öğe, başka bir şey ilk mektup.

LPSTR ** değişkenini doğru şekilde nasıl dizebilirim?

+1

Bu daha 'StringBuilder []' gibi olmalıdır. Bu parametreyi manuel olarak marşlatabilirsiniz, bkz. E.g [bu soru] (http://stackoverflow.com/q/16857034/1997232). – Sinatr

+0

@Sinatr, StringBuilder [] kullanmayı denedim ancak bu durumda şu hatayı alıyorum: "Managed Debugging Assistant 'ContextSwitchDeadlock' oluştu". Sağladığınız bağlantıya bir göz atın. – user208478

+0

Marshalling yönü nedir? In, Out, İkisi de mi? – arbiter

cevap

0

Bunu hemen kontrol edemez, ancak imza gibi görünmelidir: Elbette

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

, yardımcı olmuyor olduğunu (Sinatr önerildiği gibi) her zaman Marshal sınıfa aracılığıyla manuel sıralanırken gerçekleştirebilir.

0

bu deneyin:

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' 
      } 
     } 
    } 
}