c#调用c++ DLL返回不正确的值
本文关键字:不正确 返回 DLL 调用 c++ | 更新日期: 2023-09-27 18:05:01
我不知道如何进一步调试这个错误,所以征求意见。
本质上,我有一个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++布尔函数不正确返回