Как вызвать функцию в неуправляемой DLL из кода C #? - PullRequest
0 голосов
/ 03 апреля 2011

Как я могу вызвать следующий метод из C #, который находится в C ++ dll? Как я могу воссоздать следующую структуру в C #?


Оригинал

Метод:

LONG MyMethod (P_HOLO_INFO pInfo, LPVOID pBuffer, LPUSHORT pTracksWritten);

Структура: В этом методе используется следующая структура:

typedef struct _HOLO_INFO
{
    LONG     lHoloType;
    LONG     lStatus;
    HANDLE   lThreadHandle;
    LONG     lErrorCode;
    LONG     lDriveIndex;
    LONG     lHeight;
    SHORT    iFormat;
    INT      iStartingTrack;
    LONG     lWrite;
    LONG     lSkip;
    BOOL     bSkipZero;
    BOOL     bInvert;
    LONG     lMaxConsecutiveErrors;
    LONG     lMaxTotalErrors;
    LONG     lMostConsecutiveErrors; 
    LONG     lTotalErrors;
    LPBYTE   pBuffer;
    LPUSHORT pTracksWritten;
    LONG     bUpsideDown;
} HOLO_INFO, *P_HOLO_INFO;

Я работал в C # вот так

Метод:

[DllImport("My.dll", EntryPoint = "_MyMethod@12")]
public unsafe static extern long MyMethod(ref HOLO_INFO pInfo, Byte[] pBuffer,ref ushort pTracksWritten);

Состав:

Этот метод использует следующую структуру:

unsafe public  struct HOLO_INFO 
{
    public long  lHoloType;
    public long  lStatus;
    public long  lThreadHandle;
    public ulong lErrorCode;
    public long  lDriveIndex;
    public long  lHeight;
    public short iFormat;
    public int   iStartingTrack;
    public long  lWrite;
    public long  lSkip;
    public bool  bSkipZero;
    public bool  bInvert;
    public long  lMaxConsecutiveErrors;
    public long  lMaxTotalErrors;
    public long  lMostConsecutiveErrors; 
    public long  lTotalErrors;
    public Byte* pBuffer;
    public long* pTracksWritten;
    public long  bUpsideDown;
};

Я вызвал метод следующим образом:

  do
  {
    result = MyMethod(ref pInfo,ptrBuf,pTracksWritten);
  } while (result ==1 );

Потому что он возвращает 1, если он активен 0, если он успешно завершен 3, если он остановился из-за ошибки. если метод находится в рабочем состоянии (Active-1). он изменяет pInfo и pTracksWritten для обновления информации о состоянии.

Ответы [ 3 ]

3 голосов
/ 03 апреля 2011

много вопросов:

  • LONG должен быть объявлен как int в C #
  • РУЧКА - это IntPtr.
  • pTracksWritten отсутствует. Вам, вероятно, нужно сделать это, и pBuffer, IntPtr и использовать Marshal.AllocHGlobal для выделения памяти для них, зависит.
  • Чтобы использовать Cdecl, вам нужно CallingConvention в объявлении [DllImport].

Шансы заставить это работать не велики, если вы не можете отладить неуправляемый код. Один из базовых тестов работоспособности состоит в том, чтобы убедиться, что Marshal.SizeOf () возвращает ту же длину, что и sizeof () в неуправляемом коде. Затем убедитесь, что переданные аргументы выглядят хорошо при отладке нативного кода. Затем трижды проверьте использование указателя в собственном коде и убедитесь, что они не копируются.

0 голосов
/ 03 апреля 2011

Сделайте это:

[DllImport("My.dll", EntryPoint = "_MyMethod@12")]
int MyMethod (HOLO_INFO pInfo, IntPtr pBuffer, IntPtr pTracksWritten);

public class HOLO_INFO
{
    public int    lHoloType;
    public int    lStatus;
    public IntPtr lThreadHandle;
    public int    lErrorCode;
    public int    lDriveIndex;
    public int    lHeight;
    public short  iFormat;
    public int    iStartingTrack;
    public int    lWrite;
    public int    lSkip;
    public bool   bSkipZero;
    public bool   bInvert;
    public int    lMaxConsecutiveErrors;
    public int    lMaxTotalErrors;
    public int    lMostConsecutiveErrors; 
    public int    lTotalErrors;
    public IntPtr pBuffer;
    public IntPtr pTracksWritten;
    public int    bUpsideDown;
}

В зависимости от того, как они распределены, вам может понадобиться использовать Marshal.Copy для доступа к HOLO_INFO.pBuffer и Marshal.PtrToStructure для доступа к HOLO_INFO.pTracksWritten (или Marshal.Copy, если это массив, а не указатель на единственное значение).

0 голосов
/ 03 апреля 2011

См. Использование библиотеки Very C # в C ++

Вы можете сделать «простой» трюк [этот ответ] (ответ Используя библиотеку Very C # в C ++ ) или вы можете взглянуть на полноценное встраивание согласно моему ответу

...