c#调用c++ DLL返回不正确的值

C# calling C++ DLL returns incorrect value

本文关键字:不正确 返回 DLL 调用 c++      更新时间:2023-10-16

我不知道如何进一步调试这个错误,所以征求意见。

本质上,我有一个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初始化为false。代码中唯一将其设置为true的地方具有记录器打印。func的返回值也会定期打印到日志记录器。

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++的交互是否有什么可以解释这一点?

解决这个问题的方法是在声明之前进行以下封送处理。

[return:MarshalAs(UnmanagedType.I1)]

这可能发生,因为C定义bool为4字节整型,c++定义为1字节整型。c#团队决定在PInvoke期间使用4字节的bool值作为默认值,因为大多数系统API函数都使用4字节的bool值。如果您想要更改此行为,则必须使用封送处理来指定要使用1字节值。另一个解决方案是尝试将返回类型从bool改为int,这也应该可以解决这个问题。

要了解更多信息,请查看这里提到的答案:c# DllImport与c++布尔函数不正确返回