c ++ / clr StructureToPtr堆栈缓冲区溢出

时间:2016-03-16 15:33:51

标签: c++-cli clr

正如我在这个问题中所提出的那样c++/clr StructureToPtr exit application without any exception or error  并且由于评论,我发现退出代码是-1073740791,这意味着堆栈缓冲区溢出/溢出。那么让我发布我的两个结构,

[StructLayout(LayoutKind::Sequential)]
public ref struct ThostFtdcInputOrderField
{
    [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 11)]
    String^ BrokerID;

    [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 13)]
    String^ InvestorID;

    [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 31)]
    String^ InstrumentID;

    [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 13)]
    String^ OrderRef;

    [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 16)]
    String^ UserID;

    EnumOrderPriceTypeType OrderPriceType;

    EnumDirectionType Direction;

    EnumOffsetFlagType CombOffsetFlag;

    EnumOffsetFlagType CombHedgeFlag;

    double LimitPrice;

    int VolumeTotalOriginal;

    EnumTimeConditionType TimeCondition;

    [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 9)]
    String^ GTDDate;

    EnumVolumeConditionType VolumeCondition;

    int MinVolume;

    EnumContingentConditionType ContingentCondition;

    double StopPrice;

    EnumForceCloseReasonType ForceCloseReason;

    int IsAutoSuspend;

    [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 21)]
    String^ BusinessUnit;

    int RequestID;

    int UserForceClose;
};

The Enums

public enum struct EnumOrderPriceTypeType
{
    AnyPrice = (Byte)'1',
    LimitPrice = (Byte)'2',
    BestPrice = (Byte)'3',
    LastPrice = (Byte)'4',
    LastPricePlusOneTicks = (Byte)'5',
    LastPricePlusTwoTicks = (Byte)'6',
    LastPricePlusThreeTicks = (Byte)'7',
    AskPrice1 = (Byte)'8',
    AskPrice1PlusOneTicks = (Byte)'9',
    AskPrice1PlusTwoTicks = (Byte)'A',
    AskPrice1PlusThreeTicks = (Byte)'B',
    BidPrice1 = (Byte)'C',
    BidPrice1PlusOneTicks = (Byte)'D',
    BidPrice1PlusTwoTicks = (Byte)'E',
    BidPrice1PlusThreeTicks = (Byte)'F'
};

public enum struct EnumDirectionType
{
    Buy = (Byte)'0',
    Sell = (Byte)'1'
};
public enum struct EnumOffsetFlagType
{
    Open = (Byte)'0',
    Close = (Byte)'1',
    ForceClose = (Byte)'2',
    CloseToday = (Byte)'3',
    CloseYesterday = (Byte)'4',
    ForceOff = (Byte)'5',
    LocalForceClose = (Byte)'6'
};

public enum struct EnumTimeConditionType
{
    IOC = (Byte)'1',
    GFS = (Byte)'2',
    GFD = (Byte)'3',
    GTD = (Byte)'4',
    GTC = (Byte)'5',
    GFA = (Byte)'6'
};
public enum struct EnumVolumeConditionType
{
    AV = (Byte)'1',
    MV = (Byte)'2',
    CV = (Byte)'3'
};
public enum struct EnumContingentConditionType
{
    Immediately = (Byte)'1',
    Touch = (Byte)'2',
    TouchProfit = (Byte)'3',
    ParkedOrder = (Byte)'4',
    LastPriceGreaterThanStopPrice = (Byte)'5',
    LastPriceGreaterEqualStopPrice = (Byte)'6',
    LastPriceLesserThanStopPrice = (Byte)'7',
    LastPriceLesserEqualStopPrice = (Byte)'8',
    AskPriceGreaterThanStopPrice = (Byte)'9',
    AskPriceGreaterEqualStopPrice = (Byte)'A',
    AskPriceLesserThanStopPrice = (Byte)'B',
    AskPriceLesserEqualStopPrice = (Byte)'C',
    BidPriceGreaterThanStopPrice = (Byte)'D',
    BidPriceGreaterEqualStopPrice = (Byte)'E',
    BidPriceLesserThanStopPrice = (Byte)'F',
    BidPriceLesserEqualStopPrice = (Byte)'H'
};
public enum struct EnumForceCloseReasonType
{
    NotForceClose = (Byte)'0',
    LackDeposit = (Byte)'1',
    ClientOverPositionLimit = (Byte)'2',
    MemberOverPositionLimit = (Byte)'3',
    NotMultiple = (Byte)'4',
    Violation = (Byte)'5',
    Other = (Byte)'6',
    PersonDeliv = (Byte)'7'
};

C ++结构

struct CThostFtdcInputOrderField
{
    TThostFtdcBrokerIDType  BrokerID;
    TThostFtdcInvestorIDType    InvestorID;
    TThostFtdcInstrumentIDType  InstrumentID;
    TThostFtdcOrderRefType  OrderRef;
    TThostFtdcUserIDType    UserID;
    TThostFtdcOrderPriceTypeType    OrderPriceType;
    TThostFtdcDirectionType Direction;
    TThostFtdcCombOffsetFlagType    CombOffsetFlag;
    TThostFtdcCombHedgeFlagType CombHedgeFlag;
    TThostFtdcPriceType LimitPrice;
    TThostFtdcVolumeType    VolumeTotalOriginal;
    TThostFtdcTimeConditionType TimeCondition;
    TThostFtdcDateType  GTDDate;
    TThostFtdcVolumeConditionType   VolumeCondition;
    TThostFtdcVolumeType    MinVolume;
    TThostFtdcContingentConditionType   ContingentCondition;
    TThostFtdcPriceType StopPrice;
    TThostFtdcForceCloseReasonType  ForceCloseReason;
    TThostFtdcBoolType  IsAutoSuspend;
    TThostFtdcBusinessUnitType  BusinessUnit;
    TThostFtdcRequestIDType RequestID;
    TThostFtdcBoolType  UserForceClose;
};

类型

typedef char TThostFtdcBrokerIDType[11];
typedef char TThostFtdcInvestorIDType[13];
typedef char TThostFtdcInstrumentIDType[31];
typedef char TThostFtdcOrderRefType[13];
typedef char TThostFtdcUserIDType[16];
typedef char TThostFtdcOrderPriceTypeType;
typedef char TThostFtdcDirectionType;
typedef char TThostFtdcCombOffsetFlagType[5];
typedef char TThostFtdcCombHedgeFlagType[5];
typedef double TThostFtdcPriceType;
typedef int TThostFtdcVolumeType;
typedef char TThostFtdcTimeConditionType;
typedef char TThostFtdcDateType[9];
typedef char TThostFtdcVolumeConditionType;
typedef char TThostFtdcContingentConditionType;
typedef char TThostFtdcForceCloseReasonType;.
typedef int TThostFtdcBoolType;
typedef char TThostFtdcBusinessUnitType[21];
typedef int TThostFtdcRequestIDType;
typedef int TThostFtdcBoolType;

由于我对c ++知之甚少,所以我提供了我给出的整个演示。该演示调用此函数进行转换,

class MNConv
{
public:
    /// Native to Managed
    static M N2M(N* pNative){
        return safe_cast<M>(Marshal::PtrToStructure(IntPtr(pNative), M::typeid));
    };
    // Managed to Native
    static void M2N(M managed, N* pNative){
        Marshal::StructureToPtr(managed, IntPtr(pNative), true);
    };
};

  MNConv<ThostFtdcInputOrderField^, CThostFtdcInputOrderField>::M2N(pInputOrder, &native);

问题是这个退出代码是-1073740791,没有例外。我不确定出了什么问题,因为同一个演示实际上会成功转换其他一些结构。

1 个答案:

答案 0 :(得分:1)

使用UnmanagedType::ByValTStr时,您还必须指定编码。

由于您的C ++ typedef行都使用char,而不是wchar_t,因此您需要

[StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi)]

如果marshaller错误地使用Unicode,它将为每个字符串写入两倍的数据,溢出缓冲区并破坏附近的内存。