Search code examples
c#pointersdllunmanagedkernel32

See function signature where pointer points to


I am making calls to an unmanaged dll. The way I do so is like:

    // Kernel functions used to load dll
    #region Kernell 32

    [DllImport("kernel32")]
    static extern IntPtr LoadLibrary(string lpFileName);

    [DllImport("kernel32.dll")]
    static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

    #endregion

    public void Test()
    {            
        IntPtr dllHandle = LoadLibrary(@"C:\Program Files (x86)\SEGGER\JLinkARM_SDK_V484c\JLinkARM.dll");

        // here is a function that enables me to read data from a chip
        var ptr = GetProcAddress(loadedDllHandle, @"JLINK_HSS_Read");
        {
            Delegate1 readMem = (Delegate1)Marshal.GetDelegateForFunctionPointer(ptr, typeof(Delegate1));

            // then if I want to read an integer from memory address 0x100 I will do
            byte[] dataToRead = new byte[4];
            unsafe
            {
                fixed (byte* fixedPointer = dataToRead)
                {                        
                    // <----- FIRST CALL TO DLL WORKS GREAT!!!!!!!!!!!!!!!!
                    var retn = readMem(0x100, 4, (IntPtr)fixedPointer);  
                }
            }
        }


        // there is another function called JLINK_HSS_Start
        ptr = GetProcAddress(loadedDllHandle, @"JLINK_HSS_Start");
        {
            Delegate2 x = (Delegate2)Marshal.GetDelegateForFunctionPointer(ptr, typeof(Delegate1));                              
            unsafe
            {
                var m = x(5); // here I get an exception!
            }
        }

    }

THE EXCEPTION THAT I GET SAYS:

Additional information: A call to PInvoke function 'Jlink!Jlink.HighSpeedSampling.Hss+JLINK_HSS_Start_Handler::Invoke' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

The first function call works the second one does not

In other words I cannot call x(5). Probably because I need to pass more parameters. I do not know the signature of that method. How can I find out the signature of the method. The pointer is not null so I know the function exists. If I type the method name incorrectly I get a null pointer. One solution is to type different signatures until it does not crash. There could be so many combinations. So in short I know that the pointer is pointing to a function. How can I know the signature of that function?


Solution

  • You will need to look in the header file that comes with the SDK. One thing to watch out for is the calling convention. You may need to add [UnmanagedFunctionPointer(CallingConvention.Cdecl)] to your delegate deceleration, not doing so when required will cause this exact error (as will getting the parameters wrong).