Смотрите сигнатуру функции где указатель указывает на

1

Я звоню в неуправляемую 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 :: Invoke" имеет несбалансированный стек. Вероятно, это связано с тем, что управляемая подпись PInvoke не соответствует неуправляемой целевой сигнатуре. Убедитесь, что соглашение о вызове и параметры сигнатуры PInvoke соответствуют целевой неуправляемой подписи.

Первый вызов функции работает второй

Другими словами, я не могу назвать x (5). Наверное, потому что мне нужно передать больше параметров. Я не знаю подпись этого метода. Как я могу узнать подписи метода. Указатель не равен нулю, поэтому я знаю, что функция существует. Если я неправильно набираю имя метода, я получаю нулевой указатель. Одно из решений заключается в том, чтобы печатать разные сигнатуры до тех пор, пока они не сбой. Могло быть так много комбинаций. Короче говоря, я знаю, что указатель указывает на функцию. Как узнать подпись этой функции?

Теги:
dll
pointers
kernel32
unmanaged

2 ответа

1
Лучший ответ

Вам нужно будет посмотреть в заголовочном файле, который поставляется вместе с SDK. Одна вещь, на которую нужно обратить внимание, - это конвенция о вызове. Вам может потребоваться добавить [UnmanagedFunctionPointer(CallingConvention.Cdecl)] к замедлению делегата, не делая этого, когда это потребуется, приведет к этой точной ошибке (так же как и неправильные параметры).

0

Во втором звонке есть опечатка:

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

Вы передаете тип Delegate1 и затем передаете делегату2.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню