请参阅指针指向的函数签名

时间:2014-05-20 21:40:00

标签: c# pointers dll unmanaged kernel32

我正在调用一个非托管的dll。我这样做的方式就像:

    // 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!
            }
        }

    }

我得到的例外:

  

附加信息:调用PInvoke函数   'JLINK!Jlink.HighSpeedSampling.Hss + JLINK_HSS_Start_Handler ::调用'   堆栈不平衡。这可能是因为托管PInvoke   签名与非托管目标签名不匹配。检查一下   调用约定和PInvoke签名匹配的参数   目标非托管签名。

第一个函数调用有效,第二个函数调用

换句话说,我不能叫x(5)。可能是因为我需要传递更多参数。我不知道该方法的签名。我怎样才能找到该方法的签名。指针不为null,所以我知道函数存在。如果我错误地键入方法名称,我会得到一个空指针。一种解决方案是键入不同的签名,直到它不崩溃。可能有这么多组合。 所以总之我知道指针指向一个函数。我怎么知道该功能的签名?

2 个答案:

答案 0 :(得分:1)

您需要查看SDK附带的头文件。值得注意的是调用约定。您可能需要将[UnmanagedFunctionPointer(CallingConvention.Cdecl)]添加到代理减速中,而在需要时不会这样做会导致此确切错误(因为这会导致参数错误)。

答案 1 :(得分:0)

第二次通话中有拼写错误:

Delegate2 x = (Delegate2)Marshal.GetDelegateForFunctionPointer(ptr, typeof(Delegate1));                              

您传递的是Delegate1类型,然后转换为Delegate2。