Использование DLLImport для импорта объекта - PullRequest
2 голосов
/ 15 января 2010

У меня есть DLL для класса C ++ (SLABHIDDevice.dll). Я пытаюсь использовать функции этой DLL в приложении C # .net. DLL содержит несколько методов, которые я могу легко использовать с такими утверждениями, как этот ...

(я извиняюсь, если я неправильно понял некоторые термины, я новичок в использовании dll)

[DllImport("SLABHIDDevice.dll")]
        public static extern byte GetHidString
            (Int32 deviceIndex, Int32 vid, Int32 pid,
            Byte hidStringType, String deviceString, 
            Int32 deviceStringLength);

В документации по SLABHIDDevice.dll говорится, что он также содержит объект класса CHIDDevice. и этот объект имеет целый список функций-членов, таких как Open ();

Если я пытаюсь импортировать Open (), используя тот же синтаксис, что и выше, я получаю сообщение об ошибке, в котором говорится, что он не может найти точку входа для функции Open (). Это потому, что Open () является членом CHIDDevice?

Это состав из dll от DUMPBIN ... Три нижних функции - единственные, которые я могу заставить работать? Кто-нибудь знает, какой синтаксис мне нужно использовать, чтобы получить другие? Что означают знаки вопроса перед именами функций?

Dump of file SLABHIDDEVICE.dll

File Type: DLL

  Section contains the following exports for SLABHIDDevice.dll

    00000000 characteristics
    47E13E0F time date stamp Wed Mar 19 12:23:43 2008
        0.00 version
           1 ordinal base
          26 number of functions
          26 number of names

    ordinal hint RVA      name

          4    0 00001000 ??0CHIDDevice@@QAE@ABV0@@Z
          5    1 00001330 ??0CHIDDevice@@QAE@XZ
          6    2 00001430 ??1CHIDDevice@@UAE@XZ
          7    3 00001080 ??4CHIDDevice@@QAEAAV0@ABV0@@Z
          8    4 00020044 ??_7CHIDDevice@@6B@
          9    5 00001460 ?Close@CHIDDevice@@QAEEXZ
         10    6 00001C70 ?FlushBuffers@CHIDDevice@@QAEHXZ
         11    7 00001CA0 ?GetFeatureReportBufferLength@CHIDDevice@@QAEGXZ
         12    8 00001850 ?GetFeatureReport_Control@CHIDDevice@@QAEEPAEK@Z
         13    9 00001C80 ?GetInputReportBufferLength@CHIDDevice@@QAEGXZ
         14    A 00001BE0 ?GetInputReport_Control@CHIDDevice@@QAEEPAEK@Z
         15    B 00001A20 ?GetInputReport_Interrupt@CHIDDevice@@QAEEPAEKGPAK@Z
         16    C 00001CB0 ?GetMaxReportRequest@CHIDDevice@@QAEKXZ
         17    D 00001C90 ?GetOutputReportBufferLength@CHIDDevice@@QAEGXZ
         18    E 00001730 ?GetString@CHIDDevice@@QAEEEPADK@Z
         19    F 00001CC0 ?GetTimeouts@CHIDDevice@@QAEXPAI0@Z
         20   10 00001700 ?IsOpened@CHIDDevice@@QAEHXZ
         21   11 000014A0 ?Open@CHIDDevice@@QAEEKGGG@Z
         22   12 00001360 ?ResetDeviceData@CHIDDevice@@AAEXXZ
         23   13 00001810 ?SetFeatureReport_Control@CHIDDevice@@QAEEPAEK@Z
         24   14 00001B80 ?SetOutputReport_Control@CHIDDevice@@QAEEPAEK@Z
         25   15 000018C0 ?SetOutputReport_Interrupt@CHIDDevice@@QAEEPAEK@Z
         26   16 00001CE0 ?SetTimeouts@CHIDDevice@@QAEXII@Z
          3   17 00001320 GetHidGuid
          2   18 00001230 GetHidString
          1   19 00001190 GetNumHidDevices

  Summary

        6000 .data
        7000 .rdata
        5000 .reloc
        4000 .rsrc
       1C000 .text

Ответы [ 2 ]

3 голосов
/ 15 января 2010

Вы не можете использовать P / Invoke для вызова методов экземпляра класса C ++. Основная проблема заключается в том, что вы не можете создать объект класса, вы не можете обнаружить требуемый размер выделения памяти. Передача неявного указателя «this» в метод экземпляра является еще одной проблемой, которую необходимо передать в регистр.

Вам потребуется создать управляемую оболочку для класса, для которой требуется использование языка C ++ / CLI. Google "C ++ / CLI wrapper" для хороших хитов.

1 голос
/ 15 января 2010

C ++ использует искажение имени. Все странные символы вокруг имен ваших функций позволяют компилятору / компоновщику узнать соглашение о вызовах, параметры, тип возвращаемого значения и т. Д.

Если вы не хотите использовать искажение имен в своих функциях, вам нужно окружить их

extern "C" {
}

заявление.

См. http://en.wikipedia.org/wiki/Name_mangling

...