В C # как вызвать функцию DLL, которая возвращает неуправляемую структуру, содержащую указатель строки? - PullRequest
3 голосов
/ 10 декабря 2008

Мне дали DLL ("InfoLookup.dll"), которая внутренне распределяет структуры и возвращает на них указатели из функции поиска. Структуры содержат строковые указатели:

extern "C"
{
   struct Info
   {
      int id;
      char* szName;
   };

   Info* LookupInfo( int id );
}

В C # как я могу объявить структуру структуры, объявить вызов Interop и (при условии, что возвращается ненулевое значение) использовать строковое значение? Другими словами, как мне перевести следующее на C #?

#include "InfoLookup.h"
void foo()
{
   Info* info = LookupInfo( 0 );
   if( info != 0 && info->szName != 0 )
      DoSomethingWith( info->szName );
   // NOTE: no cleanup here, the DLL is caching the lookup table internally
}

Ответы [ 4 ]

5 голосов
/ 10 декабря 2008

Попробуйте следующий макет. Код автоматически генерируется с помощью PInvoke Interop Assistant . Ручная кодировка LookpInfoWrapper ()

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct Info {

    /// int
    public int id;

    /// char*
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
    public string szName;
}

public partial class NativeMethods {

    /// Return Type: Info*
    ///id: int
    [System.Runtime.InteropServices.DllImportAttribute("InfoLookup.dll", EntryPoint="LookupInfo")]
public static extern  System.IntPtr LookupInfo(int id) ;

    public static LoopInfoWrapper(int id) {
       IntPtr ptr = LookupInfo(id);
       return (Info)(Marshal.PtrToStructure(ptr, typeof(Info));
    }

}
2 голосов
/ 10 декабря 2008

Например, см. Это netapi32.NetShareAdd объявление взаимодействия. Он включает в себя структуру SHARE_INFO_502 с элементом public string shi502_netname. Многие другие примеры доступны на Pinvoke.net .

1 голос
/ 10 декабря 2008

Используйте Marshalling:

http://www.csharphelp.com/archives/archive63.html

0 голосов
/ 10 декабря 2008

Необходимо также реализовать структуру в C #, убедившись, что атрибуты класса Marshal используются правильно, чтобы гарантировать соответствие макета памяти неуправляемой версии.

Итак, некоторые варианты этого:

using System.Runtime.InteropServices;

[DllImport("mydll.dll")]
public static extern Info LookupInfo(int val);

[StructLayout(LayoutKind.Sequential)]
struct Info
{
   int id;
   String szName;
}

private void SomeFunction
{
   Info info = LookupInfo(0);
   //Note here that the returned struct cannot be null, so check the ID instead
   if (info.id != 0 && !String.IsNullOrEmpty(info.szName))
      DoSomethingWith(info.szName);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...