gpt4 book ai didi

c# - IndexOutOfRangeException - 无法使用 PInvoke 查看调用堆栈

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:50:59 25 4
gpt4 key购买 nike

我正在开发一个从 SerialPort 获取数据的 C# 应用程序,然后它使用一个 C++ 项目(我无法更改)来计算读取的数据。

C++ 项目正在使用一些 native C 代码,这些代码将在计算数据时调用 C# 函数。

这是使用 PInvoke 调用 C++ 函数的调用 C# 代码的一些示例:

    [DllImport("MyLib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void PacketHandler_HandlePacket(IntPtr packetHandler, IntPtr packet, int packetType);

[SuppressUnmanagedCodeSecurity]
[DllImport("MyLib.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern float DeviceManager_AddSampleToBattery(IntPtr self, float sample, double sampleRate);

[SuppressUnmanagedCodeSecurity]
[DllImport("MyLib.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern double DeviceManager_GetTimestamp(IntPtr self, int packetType);

[DllImport("MyLib.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern void PacketHandler_AddCallbackBattery(IntPtr self, Delegate @delegate);

然后,C++代码:

extern "C"
{
__declspec(dllexport) void _cdecl PacketHandler_HandlePacket(int * packetHandler, char * packet, int packetType){
PacketHandler_handlePacket((PacketHandlerStruct *)packetHandler, packet, (PacketHandlerPacketType)packetType);}
}

此 C 函数正在调用我设置如下的 C# 函数:

__declspec(dllexport) void _cdecl  PacketHandler_AddCallbackBattery(int * packetHandler, void(*f)(void * obj, unsigned short int sample)){
PacketHandlerStruct * myPointer = ((PacketHandlerStruct *)packetHandler);
myPointer->delegate.addSampleToBattery = f;
}

最后,C 代码将调用“addSampleToBattery”函数,这是此 C# 回调(其中前两个是 PInvoke 调用,就像我发布的第一个一样)

private static float CallbackBattery(IntPtr self, ushort sample)
{
var value = DeviceManager_AddSampleToBattery(DeviceManager, sample, Const.BaseBvpSampleRate);
var timestamp = DeviceManager_GetTimestamp(DeviceManager, (int)PacketHandlerPacketType.Battery);
SocketManager.OnNewBatteryArrived(value, timestamp);
return value;
}

其他细节:

C# 委托(delegate)声明如下:

 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate float DelegateBattery(IntPtr self, short sample);

private static readonly DelegateBattery DelegateCallbackBattery = CallbackBattery;

然后这样设置:

var intptrDelegate = Marshal.GetFunctionPointerForDelegate(DelegateCallbackBattery);
var a = Marshal.GetDelegateForFunctionPointer(intptrDelegate, typeof(DelegateBattery));
PacketHandler_AddCallbackBattery(packetHandler, a);

因此,一切似乎都正常,但很多时候会发生 IndexOutOfRangeException。主要问题是,即使在加载了所有符号的 Debug模式下,我也看不到抛出异常的行,因为只有反汇编 View 可用,当然我无法从中获取有意义的信息。

Unhandled Exception: 'MyProgram.exe' (Win32): 
The program '[3000] MyProgram.exe' has exited with code 0 (0x0).
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Threading.ThreadPoolWorkQueue.Dequeue(ThreadPoolWorkQueueThreadLocals tl, IThreadPoolWorkItem& callback, Boolean& missedSteal)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

谢谢!

最佳答案

IndexOutOfRangeException 对应的语义表明您试图访问距离基本内存地址太远的内存,因此您不应该尝试在内存中引用该点。 p>

考虑一个包含 3 个元素的 int 数组。如果您尝试索引 [3],即 *(base_address + (sizeof(int) * 3))* 被取消引用,以便内存中该位置的下一个 4 个字节作为 int 值提供。唯一有效的索引是 0、1 和 2,因为这些偏移量在我们为其分配空间的 3 个元素的范围内。

我们仍然需要更多代码,因为我看不出这些与异常消息有什么关系。

关于c# - IndexOutOfRangeException - 无法使用 PInvoke 查看调用堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28964993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com