Marshal.PtrToStructure触发时的AccessViolationException [英] AccessViolationException when Marshal.PtrToStructure fires
问题描述
我正在尝试使用VS2012 C#env中的native dll。
我有一个奇怪的场景:
case1:
i am trying to use a native dll from VS2012 C# env. i have a weird scenario: case1:
IntPtr p_stat = IntPtr.Zero;
dcUe.dcUeGetMacStats(_helper.Handle, out p_stat);//native function call thatallocates memory and points the pointer to it
MacStatistics stats = (MacStatistics)Marshal.PtrToStructure(p_stat, typeof(MacStatistics));
与以下Pinvoke包装:
with the following Pinvoke wrapper:
[DllImport("dcc.dll",CharSet=CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 dcUeGetMacStats(thpHandle_t handle, /* MacStatistics*/out IntPtr stats);
这是类:
[StructLayout(LayoutKind.Sequential)]
public class MacStatistics {
public u32 activeDemultFailNumber;
public u32 activeDemultySuccessNumber;
public u32 pdschTotalDataNumber;
public u16 taTimerLength;
public u32 activePdschCrcCorrectNumber;
public u32 activePdschCrcErrorNumber;
public u8 antennaPortNumber;
public u32 dlSystemRbNumber;
public u32 parseDci0SuccessNumber;
public u32 pdschCrcCorrectNumber;
public u32 pdschCrcErrorNumber;
public u32 pdschDynamicNumber;
public u32 pdschSemiStaticNumber;
public u32 receiveDci0Number;
public u32 sendPucchSuccessNumber;
public u32 sendPuschSuccessNumber;
public u32 ulSubCarrierRBNumber;
public u32 ulSymbolNumber;
public u32 ulSystemRbNumber;
};
此案例工作正常
案例2:
this case works fine case 2:
IntPtr p_stats = IntPtr.Zero;
st = dcUe.dcUeGetNasInfo(_helper.Handle, out p_stats);//nativs function call that allocates memory and points the pointer to it
NasInfo ueNasState = (NasInfo)Marshal.PtrToStructure(p_stats, typeof(NasInfo));
与以下Pinvoke包装:
with the following Pinvoke wrapper:
[DllImport("dcc.dll",CharSet=CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 dcUeGetNasInfo(thpHandle_t handle, /* NasInfo*/out IntPtr info);
这是类:
[StructLayout(LayoutKind.Sequential)]
public class NasInfo {
public EmmPlmnSelectMode plmnSelectMode;//enum
public u32 pdnQty;
public EpsPdnAddress pdnArray;
public Bool_t emmRegistred;
public Bool_t rrcConnected;
public EpsIntegrityAlgorithm integrityAlgo;//enum
public EpsCipheringAlgorithm cipheringAlgo;//enum
};
[StructLayout(LayoutKind.Sequential)]
public class EpsPdnAddress {
sqnBool_t epsIpv4AddressPresent;
u8 [] epsIpv4Address = new u8[4];
sqnBool_t epsIpv6AddressPresent;
u8 [] epsIpv6Address = new u8[8];
}
这种情况会在行中抛出AccessViolationException:
this case throws AccessViolationException in the line:
NasInfo ueNasState = (NasInfo)Marshal.PtrToStructure(p_stats, typeof(NasInfo));
我真的很困惑,本机功能改变了ptr值,所以似乎做了分配,编组失败。
i am really baffled, the native functions does change the ptr value so it seems to do the allocation but the marshalling fails.
请帮助
感谢
mosh。
please helps thanks mosh.
[更新解决]
public class NasInfo {
public EmmPlmnSelectMode plmnSelectMode;//enum
public u32 pdnQty;
public EpsPdnAddress pdnArray;
public Bool_t emmRegistred;
public Bool_t rrcConnected;
public EpsIntegrityAlgorithm integrityAlgo;//enum
public EpsCipheringAlgorithm cipheringAlgo;//enum
};
已更改为
public class NasInfo {
public EmmPlmnSelectMode plmnSelectMode;//enum
public u32 pdnQty;
public /*EpsPdnAddress*/ IntPtr pdnArray;
public Bool_t emmRegistred;
public Bool_t rrcConnected;
public EpsIntegrityAlgorithm integrityAlgo;//enum
public EpsCipheringAlgorithm cipheringAlgo;//enum
};
并且marshelling的工作
,但我已经失去了类型的安全,有没有办法包含IntPtr并且仍然有一些关于原始struct / class(在这种情况下为EpsPdnAddress)的细节
and the marshelling works but i have lost the type safe, is there a way to wrap the IntPtr and still have some detail about the original struct/class (EpsPdnAddress in this case)
推荐答案
请检查大小本机和托管结构匹配
Please check the size of the native and managed structs are matched
这篇关于Marshal.PtrToStructure触发时的AccessViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!