-1

I'm trying to call a dll function in C# with a paramter that is mentioned in the documentation as "...If pfn = NULL is passed, the call is synchronous. ". I'm actually passing NULL (IntPtr.Zero) to it, so the method should be called synchronous. Now I'm getting all the time a "FatalExecutionEngineError", ErrorCode 0xc0000005 when I call the method and I think that the synchronization is the problem.

So my question: How can I call a C DLL method synchronous in C#? Or do I need for that method a callback function?

The dll comes from the Siemens WinCC Runtime, the documentation about the methods are here (GetFocus Method is on page 1923): https://cache.industry.siemens.com/dl/files/216/109755216/att_940522/v1/WCC_PReference_en-US.pdf?download=true

The dll import:

[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);

The method call:

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

The struct of the FOCUSINFO in C#

[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;
        }

The struct of the FOCUSINFO in the PDLRTAPI.h

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

The typedef of the ADRMODE is:

typedef     unsigned short  ADRMODE;
  • Usually error code 5 is "access denied" so my guess is that the user running the application (and the dll) does not have acess to whatever directory or something the dll is trying to access. – nivs1978 Oct 20 '20 at 13:48
  • This could make sense, since if the WinCC runtime is stopped, the method returns the expected boolean "false" which means according to the documentation there is an error, maybe because the runtime is not running? – Eicher16ps Oct 20 '20 at 14:26
  • *Update*: Tried as administrator, same result – Eicher16ps Oct 20 '20 at 14:34
  • @nivs1978 It's not access denied. That's a Win32 error code with value 5. This is `0xc0000005` which is the NTSTATUS code for an access violation. – David Heffernan Oct 20 '20 at 14:46
  • `LayoutKind.Auto` is wrong, should be `LayoutKind.Sequential`. There could equally be plenty of other errors. If I were you I'd start by making sure I can call the API functions in C++ code. – David Heffernan Oct 20 '20 at 14:48
  • Make sure an instance of FOCUSINFO is allocated before each call. – jdweng Oct 20 '20 at 15:06
  • Perhaps the DLL has a log where you can see what went wrong. The documentation should have some information about this. – nivs1978 Oct 22 '20 at 10:46

1 Answers1

0

Update:

It turned out, that the FOCUSINFO parameter needs to be only an "out" parameter and not a "reference". So the correct code is:

[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);

So to everyone who is running into this problem: Check the arguments and especially the data-types to the dll function twice...

Anyway, thanks to everyone who tried to help me.