【问题标题】:C# - Call C DLL function synchronousC# - 同步调用 C DLL 函数
【发布时间】:2020-10-20 13:44:01
【问题描述】:

我正在尝试使用文档中提到的参数“...如果传递 pfn = NULL,则调用是同步的。”在 C# 中调用 dll 函数。我实际上将 NULL (IntPtr.Zero) 传递给它,所以该方法应该被称为同步的。现在,当我调用该方法时,我总是收到“FatalExecutionEngineError”,ErrorCode 0xc0000005,我认为同步是问题所在。

所以我的问题是:如何在 C# 中调用同步的 C DLL 方法?还是该方法需要回调函数?

dll 来自 Siemens WinCC Runtime,有关方法的文档在这里(GetFocus 方法在第 1923 页):https://cache.industry.siemens.com/dl/files/216/109755216/att_940522/v1/WCC_PReference_en-US.pdf?download=true

dll 导入:

[DllImport("PDLRTAPI.dll", EntryPoint = "PDLRTGetFocusW", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
        public static extern bool PDLRTGetFocus([In] UInt16 adrMode,
                                             [In, Out] ref FOCUSINFO pFocusInfo,
                                             [In, Out] IntPtr pfn,
                                             [In, Out] IntPtr pvUser,
                                             [In, Out] [MarshalAs(UnmanagedType.LPStruct)]
                                                       CMN_ERROR_MANCLASS pError);

方法调用:

pdlrtapiDLLWrapper.FOCUSINFO focusinfo = new pdlrtapiDLLWrapper.FOCUSINFO();
            bRet = pdlrtapiDLLWrapper.PDLRTGetFocus((UInt16)1, ref focusinfo, IntPtr.Zero, IntPtr.Zero, err);

C#中FOCUSINFO的结构体

[StructLayout(LayoutKind.Auto, CharSet = CharSet.Unicode)]
        public class FOCUSINFO
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string szPicture;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string szObject;
        }

PDLRTAPI.h中FOCUSINFO的结构体

typedef struct tagFOCUSINFOW
{
    WCHAR           szPicture[256];
    WCHAR           szObject[256];
} FOCUSINFOW, *LPFOCUSINFOW;

ADRMODE 的 typedef 是:

typedef     unsigned short  ADRMODE;

【问题讨论】:

  • 通常错误代码 5 是“拒绝访问”,所以我的猜测是运行应用程序(和 dll)的用户无法访问任何目录或 dll 试图访问的内容。跨度>
  • 这可能是有道理的,因为如果 WinCC 运行时停止,该方法会返回预期的布尔值“false”,这意味着根据文档存在错误,可能是因为运行时没有运行?
  • 更新:以管理员身份尝试,结果相同
  • @nivs1978 这不是拒绝访问。这是一个值为 5 的 Win32 错误代码。这是0xc0000005,这是访问冲突的 NTSTATUS 代码。
  • LayoutKind.Auto 错误,应该是LayoutKind.Sequential。同样可能还有很多其他错误。如果我是你,我会首先确保我可以在 C++ 代码中调用 API 函数。

标签: c# dllimport siemens wincc


【解决方案1】:

更新:

事实证明,FOCUSINFO 参数只需要是“out”参数而不是“reference”。 所以正确的代码是:

[DllImport("PDLRTAPI.dll", EntryPoint = "PDLRTGetFocusW", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
        public static extern bool PDLRTGetFocus([In] UInt16 adrMode,
                                             [Out] FOCUSINFO pFocusInfo,
                                             [In, Out] IntPtr pfn,
                                             [In, Out] IntPtr pvUser,
                                             [In, Out] [MarshalAs(UnmanagedType.LPStruct)] CMN_ERROR_MANCLASS pError);

所以对于遇到这个问题的每个人:检查参数,尤其是 dll 函数的数据类型两次...

无论如何,感谢所有试图帮助我的人。

【讨论】:

    猜你喜欢
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多