繁体   English   中英

C ++到C#回调期间“变量周围的堆栈已损坏”

[英]“stack around the variable is corrupted” during c++ to c# callback

我声明了这样的c ++结构:

struct orders
{
signed long long replID; // i8
signed long long replRev; // i8
signed long long replAct; // i8
signed long long id_ord; // i8
signed int status; // i4
signed char action; // i1
signed int isin_id; // i4
signed char dir; // i1
char price[11]; // d16.5
signed int amount; // i4
signed int amount_rest; // i4
signed long long id_ord1; // i8
signed int init_amount; // i4

};

和类似的C#结构:

public struct Orders
{
    public long replID; // i8
    public long replRev; // i8
    public long replAct; // i8
    public long id_ord; // i8
    public int status; // i4
    public char action; // i1
    public int isin_id; // i4
    public char dir; // i1
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
    public char[] price; // d16.5
    public int amount; // i4
    public int amount_rest; // i4
    public long id_ord1; // i8
    public int init_amount; // i4
}

我通过c ++传递结构:

__declspec(dllexport) void InitializeCallbacks(OrdersCallback ordersCallbackAddress_) {

OrdersCallback ordersCallbackFunction = ordersCallbackAddress_;
orders test;
test.init_amount = 123;
ordersCallbackFunction(&test);
}

到C#:

        OrdersCallback ordersCallback =
            delegate(ref Orders value)
            {
                Console.WriteLine("C# Orders call received = " +
                    " init_amount = " + value.init_amount);
            };
        InitializeCallbacks(ordersCallback);

我可以在控制台“ init_amount = 123”上阅读我认为可以证明调用按预期工作并且结构正确对齐的内容。 但是,在调试时,我收到此错误: “运行时检查失败#2-变量test周围的堆栈已损坏。”

如果我对此行发表评论ordersCallbackFunction(&test); 然后错误消失了。 我的代码有什么问题?

upd我忘了提到在c ++方面,我有#pragma pack(push, 4)

最有可能的是,堆栈损坏是由于您错误的假设,即C#中的char类型与C ++的大小相同。 C#中的char是UTF-16代码点。 有关详细信息,请参见MSDN 如果您想要类似于C ++ char的东西,请考虑bytesbyte

您的结构打包很可能不是奇偶校验(通过创建每个结构并检查分配的大小,您应该能够在调试器中看到这一点)。

在C ++中检查“ #pragma pack”,如果您的结构已压缩,请对C#结构执行以下操作:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct Orders {
...
}

而且,正如Nathan所指出的那样,您对Char的假设也不成立。 您将要在C ++中使用char或unsigned char并将其映射到C ++中的sbyte或byte。

我还建议您按照如下所示对结构进行显式重新排序,以使您可以同时控制C ++和C#端:

struct orders {
    signed long long replID; // i8
    signed long long replRev; // i8
    signed long long replAct; // i8
    signed long long id_ord; // i8
    signed long long id_ord1; // i8
    signed int status; // i4
    signed int isin_id; // i4
    signed int amount; // i4
    signed int amount_rest; // i4
    signed int init_amount; // i4
    signed char action; // i1
    signed char dir; // i1
    char price[11]; // d16.5

};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM