1

重複投稿失礼します。

やあ

DLL からのリンク リストのマーシャリングに問題があります。

------C++ の構造と機能--------

struct localeInfo { 
   WCHAR countryName[BUFFER_SIZE];
   WCHAR localeName[BUFFER_SIZE]; 
   localeInfo *next; 
}

int GetSystemLocales(localeInfo **ppList);

-----------C#宣言-----------

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
private struct LocaleInfo { 
   public string countryName; 
   public string localeName; 
   public IntPtr next; 
};

[DllImport("systemLocales.dll")]
private static extern int GetSystemLocales(ref IntPtr ppList);


int main() 
{ 
   var pListHead = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); 
   try 
   { 
       GetSystemLocales(ref pListHead); 
       var deref1(IntPtr)Marshal.PtrToStructure(pListHead, typeof(IntPtr)); 
       var deref2 = (LocaleInfo)Marshal.PtrToStructure(deref1, typeof(LocaleInfo)); 
   } 
   finally 
   { 
      Marshal.FreeHGlobal(pListHead); 
   }

}

deref2 宣言で FatalExecutionEngine Exception が発生します。リンクされたリストを元に戻し、その内容にアクセスする方法がわかりません。

リンク リストを取得するために作成した C++ コードを次に示します。C#で動作するようなものが欲しいです。

localeInfo *pHead = NULL; 
localeInfo *pTemp; 
GetSystemLocales(&pHead);

for(pTemp = pHead; pTemp!=NULL; pTemp = pTemp->next)
{
        wprintf(L"Display Name : %s (%s) \n", pTemp->countryName, pTemp->localeName);
}
4

2 に答える 2

1

私はこれらの線に沿ってあなたの他の質問に答えました。Shay のstruct定義はその一部ですが、私Mainも修正しました。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct LocaleInfo
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
    public string countryName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
    public string localeName;
    public IntPtr next;
};

[DllImport("systemLocales.dll")]
private static extern int GetSystemLocales(ref IntPtr ppList);

static void Main()
{ 
    IntPtr pList = IntPtr.Zero;
    GetSystemLocales(ref pList);
    while (pList != IntPtr.Zero)
    {
        var info = (LocaleInfo)Marshal.PtrToStructure(pList, typeof(LocaleInfo));
        Console.WriteLine("Display Name : {0} ({1}) ", info.countryName, info.localeName);
        Marshal.FreeHGlobal(pList);
        pList = info.next;
    }
}

あなたは本当に他の質問を閉じるべきです - 私はあなたがこれも投稿したことに運が良かっただけです。

于 2009-06-05T19:03:01.337 に答える
1

これを試して:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct LocaleInfo { 
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
   public string countryName; 
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
   public string localeName; 
   public IntPtr next; 
};
于 2009-06-04T15:24:36.177 に答える