PInvoke и EntryPointNotFoundException - PullRequest
1 голос
/ 04 мая 2011

Я не могу понять, что не так с pinvoke ниже, что приводит к EntryPointNotFoundException:

Функция в C с объявлением структуры:

    extern "C"__declspec (dllimport) __stdcall
    LONG NET_DVR_Login_V30 (char *sDVRIP,  WORD wDVRPort,  char *sUserName,
                        char *sPassword,  LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo);

    typedef struct
    {
        BYTE sSerialNumber[48]; 
        BYTE byAlarmInPortNum;
        BYTE byAlarmOutPortNum;
        BYTE byDiskNum;
        BYTE byDVRType;
        BYTE byChanNum;
        BYTE byStartChan;
        BYTE byAudioChanNum;
        BYTE byIPChanNum;
        BYTE byZeroChanNum;
        BYTE byMainProto;
        BYTE bySubProto;
        BYTE bySupport;
        BYTE byRes1[20];
    }NET_DVR_DEVICEINFO_V30,  *LPNET_DVR_DEVICEINFO_V30; 

Импорт в C #, объявление структуры и pinvoke:

    [DllImport("SDK.dll", SetLastError = true,
        CallingConvention = CallingConvention.StdCall)]
        public extern static int NET_DVR_Login_V30(
            [MarshalAs(UnmanagedType.LPStr)] string sDVRIP,
            ushort wDVRPort,
            [MarshalAs(UnmanagedType.LPStr)] string sUserName,
            [MarshalAs(UnmanagedType.LPStr)] string sPassword,
            ref NET_DVR_DEVICEINFO_V30 lpDeviceInfo);

    [StructLayout(LayoutKind.Sequential,
        CharSet = CharSet.Ansi)]
        public struct NET_DVR_DEVICEINFO_V30
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
            public string sSerialNumber;
            public byte byAlarmOutPortNum;
            public byte byDiskNum;
            public byte byDVRType;
            public byte byChanNum;
            public byte byStartChan;
            public byte byAudioChanNum;
            public byte byIPChanNum;
            public byte byZeroChanNum;
            public byte byMainProto;
            public byte bySubProto;
            public byte bySupport;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string byRes1;
        }

           NET_DVR_DEVICEINFO_V30 deviceInfo = new NET_DVR_DEVICEINFO_V30();
           int result = Functions.NET_DVR_Login_V30(ip, port, user,
                                                 password, ref deviceInfo);

Я проверил имя функции через dumpbin, и оно не искажено. Поэтому мне интересно, почему возникает исключение EntryPointNotFoundException, если, например, с параметрами что-то не так, может произойти ошибка PInvokeStackImbalance, скажем. Есть идеи, что может быть не так с этим pinvoke?

Ответы [ 2 ]

1 голос
/ 04 мая 2011

Существует инструмент под названием Dependency Walker (depends.exe), который поможет отладить эту проблему путем отображения таблицы импорта / экспорта вашей SDK.DLL - я бы посмотрел на это. Еще одна вещь, которую может (это мне кажется подозрительным), заключается в том, что, поскольку вы используете char *, .NET добавляет «A» в конце имени вашей функции. Хотя это может быть лысиной.

0 голосов
/ 04 мая 2011

Очевидно, что есть несоответствие имени.Поэтому необходимо убедиться, что обе стороны интерфейса используют одно и то же имя:

  • При экспорте функции из DLL в качестве stdcall она будет оформлена.Вы можете избежать этого оформления, используя файл .def.
  • При импорте с использованием P / Invoke вам нужно запретить добавление суффикса W или A.Сделайте это, установив поле ExactSpelling для DllImportAttribute в true.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...