【问题标题】:C# calling C++ DLL returns incorrect valueC# 调用 C++ DLL 返回不正确的值
【发布时间】:2016-09-01 07:26:33
【问题描述】:

我没有进一步的想法如何调试这个错误,所以寻求建议。

基本上,我有一个 C++ DLL,它有一个布尔函数

class Point
{
   Public: 
   double x;
   double y;

   // lots of operators
}

typedef struct SomeStructParent
{
    bool isValid;

    int64_t StartTime;
    int64_t EndTime;
} SomeStructParent;

typedef struct SomeStruct : SomeStructParent
{
    Point Center;
} SomeStruct;

bool func(SomeStruct & arg)
   { return some_var; }

some_var 初始化为假。代码中唯一设置为 true 的地方有一个记录器打印。 func的返回值也会定期打印到logger。

C# 像这样导入函数:

public struct EtPoint
    {
        public double x;
        public double y;
    }

[StructLayout(LayoutKind.Sequential)]
public struct SomeStruct 
    {
        bool isValid;

        // in milliseconds using tracker epoch
        public long StartTime;
        long EndTime;

        public EtPoint Center;       
    }

[DllImport("ETHAL.dll", EntryPoint = "func", CallingConvention = CallingConvention.Cdecl)]
public static extern bool func(ref SomeStruct data);

在某些情况下,从 C# 调用 func 会返回 true,即使记录器将其显示为 false - 常规打印为 false,并且不会出现显示已设置的行。使用修改后的函数 bool funcArg(SomeStruct & arg, bool & ret) { ret = some_var; }ret 在相同条件下可靠地为假。

也许是最烦人/最令人困惑的部分:在func 中添加调试打印时,它会返回正确的值。当我添加Sleep(500) 时也会发生同样的情况。这让我怀疑某种多线程恶作剧,但正如我所说 - 代码中只有一个地方 some_var 被分配为 true,并且在此运行中没有达到。

C# 和 C++ 的交互是否可以解释这一点?

【问题讨论】:

  • 如果你把C#代码放在那里就好了;)
  • 导致 UB 的函数签名不正确?多线程?程序的其他部分写在它不写的内存中?没有更多信息很难说..
  • 我添加了 C# 调用。其余的......好吧,我不希望 SO 在我的代码中找到多线程错误,我专门询问 C# 和 C++ 交互,看看那里是否存在一些我不知道的常见陷阱。跨度>
  • 什么是 SomeStruct,它在 C# 和 C++ 中的布局是否完全相同?
  • 我用两种语言添加了结构的定义。

标签: c# c++ debugging dll


【解决方案1】:

您的问题的解决方案可以是在您的声明之前使用以下编组。

[return:MarshalAs(UnmanagedType.I1)]

这可能是因为 C 将 bool 定义为 4 字节 int 而 C++ 将其定义为 1 字节。 C# 团队决定在 PInvoke 期间使用 4 字节 bool 作为默认值,因为大多数系统 API 函数使用 4 字节值作为 bool。如果要更改此行为,则必须通过编组指定要使用 1 字节值来执行此操作。另一种解决方案是尝试将返回类型从 bool 更改为 int,这也应该可以解决问题。

有关更多信息,请查看此处提到的答案: C# DllImport with C++ boolean function not returning correctly

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 2017-11-04
    • 1970-01-01
    • 2020-10-31
    相关资源
    最近更新 更多