gpt4 book ai didi

c# - 将结构内的整数指针编码为回调

转载 作者:行者123 更新时间:2023-11-30 16:48:57 24 4
gpt4 key购买 nike

我有一个用于回调的 C 结构,我需要将其编码到 C# .NET:

struct CTMDeviceInfo {
enum CTMDeviceType eDeviceType;
char * szDeviceModel;
char * szDeviceSubModel;
int32_t * piDeviceID;
};

这是我的 C# 版本:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CTMDeviceInfo
{
public CTMDeviceType deviceType;

[MarshalAs(UnmanagedType.LPStr)]
public string deviceModel;

[MarshalAs(UnmanagedType.LPStr)]
public string deviceSubModel;

public IntPtr deviceId;
};

在另一个结构中使用:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CTMDeviceError
{
public CTMDeviceInfo deviceInfo;

[MarshalAs(UnmanagedType.I4)]
public Int32 resultCode;

[MarshalAs(UnmanagedType.I4)]
public Int32 extendedResultCode;

public IntPtr denomination;

public IntPtr changeDue;
};

我的问题是“IntPtr deviceId”在每次回调时并不总是返回正确的值。

我期望整数值为 5、15 或 16,但它不断返回随机值,例如 106、865412、652272 等。

我不知道我做错了什么。不过,我所做的是防止使用 GCHandle 对托管代码中的回调进行垃圾收集。

以下是我的操作顺序:

从我的非托管代码中,我有这个 CDECL 回调方法:

void ctm_add_device_error_event_handler(CTMDeviceErrorCallback);

typedef void (CTMDeviceErrorCallback) (struct CTMEventInfo, struct CTMDeviceError );

这是我的托管代码:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void OnDeviceErrorCallBack(CTMEventInfo evtInfo, CTMDeviceError deviceError);

[DllImport("libctmclient-0.dll", EntryPoint = "ctm_add_device_error_event_handler", CallingConvention = CallingConvention.Cdecl)]
public static extern void AddDeviceErrorEventHandler([MarshalAs(UnmanagedType.FunctionPtr)] OnDeviceErrorCallBack deviceErrorCallBack);

OnDeviceErrorCallBack deviceErrorCallback;
GCHandle deviceErrorCallbackGCHandle;

deviceErrorCallback = new OnDeviceErrorCallBack(OnDeviceError);
deviceErrorCallbackGCHandle = GCHandle.Alloc(deviceErrorCallback);
AddDeviceErrorEventHandler(deviceErrorCallback);

这是处理回调的地方:

public void OnDeviceError(CTMEventInfo evtInfo, CTMDeviceError deviceError)
{
int nDeviceId = Marshal.ReadInt32(deviceError.deviceInfo.deviceId);
}

我尝试使用unsafe直接使用指针,但问题还是一样。

public unsafe int *deviceId; //instead of IntPtr

int nDeviceId = 0;

unsafe
{
nDeviceId = *(deviceError.deviceInfo.deviceId);
}

我确信我的非托管代码返回了正确的值,因为我有日志,但当它到达我的托管代码时,不知何故返回了另一个值。就好像它正在阅读不同的引用文献或其他东西。

希望能帮助我,因为我现在被困了一段时间。谢谢!

最佳答案

使用以下 C# 结构。您可以在稍后的代码中从指针获取两个字符串。 :

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CTMDeviceInfo
{
public CTMDeviceType deviceType;

public IntPtr deviceModel;

public IntPtr deviceSubModel;

public IntPtr deviceId;
};

关于c# - 将结构内的整数指针编码为回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42785337/

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