0

我声明了这样的 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)

4

2 回答 2

3

Most likely, the stack corruption is due to your flawed assumption that a char type in C# is the same size as that of C++. char in C# is a UTF-16 codepoint. See MSDN for details. If you want something similar to a C++ char, consider byte or sbyte.

于 2013-06-20T18:26:37.717 回答
1

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

检查 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

};

于 2013-06-20T18:28:59.393 回答