简体   繁体   English

PInvoke 和 EntryPointNotFoundException

[英]PInvoke and EntryPointNotFoundException

I can't understand what is wrong with a pinvoke below which results into an EntryPointNotFoundException:我无法理解下面导致 EntryPointNotFoundException 的 pinvoke 有什么问题:

A function in C with a structure declaration: C 中的 function 具有结构声明:

    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; 

The import in C#, the structure declaration and the pinvoke: 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);

I inspected the function name via dumpbin and it is not mangled.我通过垃圾箱检查了 function 名称,它没有损坏。 So I wonder why an EntryPointNotFoundException occurs, if anything were wrong with the parameters for example, a PInvokeStackImbalance error would occur, let's say.所以我想知道为什么会发生 EntryPointNotFoundException,如果参数有任何问题,例如,会发生 PInvokeStackImbalance 错误,比如说。 Any ideas what could be wrong with this pinvoke?任何想法这个pinvoke可能有什么问题?

There is a tool called Dependency Walker ( depends.exe ) that will help debug this issue by displaying the import/export table of your SDK.DLL - I'd take a look at that.有一个名为 Dependency Walker ( depends.exe ) 的工具,它可以通过显示 SDK.DLL 的导入/导出表来帮助调试此问题 - 我来看看。 One other thing that might (this seems suspect to me) be happening is, that since you're using char*, .NET is adding an "A" on the end of your function name.可能发生的另一件事(这对我来说似乎很可疑)是,由于您使用的是 char*,因此 .NET 在您的 function 名称的末尾添加了一个“A”。 That could be balderdash though.不过,这可能是胡说八道。

Clearly there is a name mismatch.显然名称不匹配。 You therefore need to make sure that both sides of the interface use the same name:因此,您需要确保界面的两侧使用相同的名称:

  • When exporting the function from the DLL as stdcall it will be decorated.当从 DLL 作为标准调用导出 function 时,它将被装饰。 You can avoid this decoration by using a.def file.您可以通过使用 a.def 文件来避免这种装饰。
  • When importing using P/Invoke you need to suppress the addition of a W or A suffix.使用 P/Invoke 导入时,您需要禁止添加WA后缀。 Do so by setting the ExactSpelling field of the DllImportAttribute to true .通过将DllImportAttributeExactSpelling字段设置为true来实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM