【发布时间】: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