2017-03-28 31 views
5

mam metodę w unmaged obiektu COM który próbuję MarshallJak obsłużyć LPSTR ** w .NET?

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

Ale nie mogę dowiedzieć się, w odpowiedni sposób, aby zebrać się LPSTR ** przedmiotów. To powinna być lista przedmiotów. Jeśli jednak spróbujesz zrobić coś takiego:

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

Otrzymuję tylko pierwszą literę pierwszego przedmiotu i nic więcej.

Jak poprawnie zmanować zmienną LPSTR **?

+1

ten powinien być bardziej jak StringBuilder '[]'. Możesz kontrolować ten parametr ręcznie, patrz np. [To pytanie] (http://stackoverflow.com/q/16857034/1997232). – Sinatr

+0

@Sinatr, Próbowałem używać StringBuilder [], ale w tym przypadku otrzymuję ten błąd: "Wystąpił Managed Debugging Assistant" Wystąpił ContextSwitchDeadlock ". Rzucimy okiem na podany przez ciebie link. – user208478

+0

Co to jest kierunek rozrządowy? In, Out, Both? – arbiter

Odpowiedz

0

Nie mogę sprawdzić go teraz, ale podpis powinien wyglądać następująco:

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

Oczywiście, to nie pomoże, zawsze można przeprowadzić ręczną rozrządowych poprzez Marshal klasy (jak sugeruje Sinatr).

0

Spróbuj tego:

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' 
      } 
     } 
    } 
} 
Powiązane problemy