gpt4 book ai didi

c# - P/调用互操作助手 : Is this actually correct?

转载 作者:搜寻专家 更新时间:2023-10-31 02:00:43 32 4
gpt4 key购买 nike

我在 C++ 中有以下结构:(使用 pragma pack 1)

typedef struct _wfs_cdm_physicalcu
{
LPSTR lpPhysicalPositionName;
CHAR cUnitID[5];
ULONG ulInitialCount;
ULONG ulCount;
ULONG ulRejectCount;
ULONG ulMaximum;
USHORT usPStatus;
BOOL bHardwareSensor;
} WFSCDMPHCU, * LPWFSCDMPHCU;

typedef struct _wfs_cdm_cashunit
{
USHORT usNumber;
USHORT usType;
LPSTR lpszCashUnitName;
CHAR cUnitID[5];
CHAR cCurrencyID[3];
ULONG ulValues;
ULONG ulInitialCount;
ULONG ulCount;
ULONG ulRejectCount;
ULONG ulMinimum;
ULONG ulMaximum;
BOOL bAppLock;
USHORT usStatus;
USHORT usNumPhysicalCUs;
LPWFSCDMPHCU *lppPhysical;
} WFSCDMCASHUNIT, * LPWFSCDMCASHUNIT;


typedef struct _wfs_cdm_cu_info
{
USHORT usTellerID;
USHORT usCount;
LPWFSCDMCASHUNIT *lppList;
} WFSCDMCUINFO, * LPWFSCDMCUINFO;

P/Invoke Interop Assistant 给我以下输出:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi, Pack = 1)]
public struct WFSCDMPHCU {

/// LPSTR->CHAR*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string lpPhysicalPositionName;

/// CHAR[5]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=5)]
public string cUnitID;

/// ULONG->unsigned int
public uint ulInitialCount;

/// ULONG->unsigned int
public uint ulCount;

/// ULONG->unsigned int
public uint ulRejectCount;

/// ULONG->unsigned int
public uint ulMaximum;

/// USHORT->unsigned short
public ushort usPStatus;

/// BOOL->int
public int bHardwareSensor;
}

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi, Pack = 1)]
public struct WFSCDMCASHUNIT {

/// USHORT->unsigned short
public ushort usNumber;

/// USHORT->unsigned short
public ushort usType;

/// LPSTR->CHAR*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string lpszCashUnitName;

/// CHAR[5]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=5)]
public string cUnitID;

/// CHAR[3]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=3)]
public string cCurrencyID;

/// ULONG->unsigned int
public uint ulValues;

/// ULONG->unsigned int
public uint ulInitialCount;

/// ULONG->unsigned int
public uint ulCount;

/// ULONG->unsigned int
public uint ulRejectCount;

/// ULONG->unsigned int
public uint ulMinimum;

/// ULONG->unsigned int
public uint ulMaximum;

/// BOOL->int
public int bAppLock;

/// USHORT->unsigned short
public ushort usStatus;

/// USHORT->unsigned short
public ushort usNumPhysicalCUs;

/// LPWFSCDMPHCU*
public System.IntPtr lppPhysical;
}

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
public struct WFSCDMCUINFO {

/// USHORT->unsigned short
public ushort usTellerID;

/// USHORT->unsigned short
public ushort usCount;

/// LPWFSCDMCASHUNIT*
public System.IntPtr lppList;
}

但是,当使用 Marshal.PtrToStruct(例如,在 WFSCDMCUINFO.lppList 上)时,我得到了垃圾;使用 Visual Studio 查看内存时,我在另一个内存条目中看到了实际内容(不是 lppList 本身)。

这些转换是否正确?我对 P/Invoke Interop Assistant 的信任是错误的吗?

编辑:

这是我用来 Marshal 到/从 IntPtr 的代码。我知道 Thread 的想法很糟糕,但我稍后会谈到......

    public static IntPtr GetIntPtr(this object obj) {
try {
var handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
var thread = new Thread(() => {
Thread.Sleep(20000);
handle.Free();
});
thread.Start();

return handle.AddrOfPinnedObject();
} catch (ArgumentException) {
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));

Marshal.StructureToPtr(obj, ptr, false);

return ptr;
}
}

public static T FromIntPtr<T>(this IntPtr ptr) {
if (ptr == IntPtr.Zero)
return default(T);

return (T) Marshal.PtrToStructure(ptr, typeof (T));
}

最佳答案

我没有深入研究结构,但看起来生成的签名肯定是正确的。这些结构中没有什么特别棘手的,所有类型都适当匹配。

问题可能出在 lppList 参数的编码上。你能给出一个快速示例,说明你如何 1) 取回这些数据和 2) 尝试编码 lppList 的代码。

如果在原始结构上使用了#pragma pack,也可能会出现问题。 PInvoke Interop Assistant 不会尝试解释 pack 命令。您可能必须手动调整结构上的该设置。

编辑

一个问题可能是 lpPhysicalPositionName 和 lpPhysicalCashUnit 参数。尝试将它们切换为 IntPtr 与 String 并删除 Marshal 属性。

警告:我编写了这个工具,所以我对它的可靠性有很大的偏见:)

关于c# - P/调用互操作助手 : Is this actually correct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1639721/

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