参见指针指向的函数签名
本文关键字:函数 指针 | 更新日期: 2023-09-27 18:04:14
我正在调用非托管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)。可能是因为我需要传递更多的参数。我不知道那个方法的签名。我怎样才能找到方法的签名?指针不为空,所以我知道函数存在。如果我输入的方法名不正确,我得到一个空指针。一种解决方案是输入不同的签名,直到它不会崩溃。可能有很多组合。所以简而言之,我知道指针指向一个函数。我怎么知道这个函数的特征?
您需要查看SDK附带的头文件。需要注意的一件事是呼叫惯例。您可能需要将[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
添加到您的委托减速中,在需要时不这样做将导致此确切错误(将获得错误的参数)。
您的第二个呼叫有一个错别字:
Delegate2 x = (Delegate2)Marshal.GetDelegateForFunctionPointer(ptr, typeof(Delegate1));
传递的是Delegate1的类型,然后强制转换为Delegate2。