2017-03-28 3 views
5

J'ai une méthode dans l'objet COM unmaged que je suis en train de Marshall:Comment marshaler LPSTR ** dans .NET?

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

Mais je ne peux pas trouver la bonne façon de maréchal en LPSTR ** articles. C'est censé être une liste d'éléments. Toutefois, si essayer de faire quelque chose comme ceci:

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

Je ne reçois la première lettre du premier élément et rien d'autre.

Comment puis-je marshaler correctement la variable LPSTR **?

+1

Cela devrait être plus comme 'StringBuilder []'. Vous pouvez marshaler ce paramètre manuellement, voir par exemple [cette question] (http://stackoverflow.com/q/16857034/1997232). – Sinatr

+0

@Sinatr, j'ai essayé d'utiliser StringBuilder [] mais dans ce cas je reçois cette erreur: "Managed Debugging Assistant 'ContextSwitchDeadlock' s'est produit". Jetez un oeil sur le lien que vous avez fourni cependant. – user208478

+0

Quelle est la direction de triage? Dans, dehors, les deux? – arbiter

Répondre

0

Je ne peux pas le vérifier en ce moment, mais la signature devrait ressembler à cela:

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

Bien sûr, il est ne fonctionne pas, vous pouvez toujours effectuer marshalling manuelle via Marshal classe (comme Sinatr suggéré).

0

Essayez ceci:

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