带有 C++ 布尔函数的 C# DllImport 没有正确返回 [英] C# DllImport with C++ boolean function not returning correctly

查看:21
本文介绍了带有 C++ 布尔函数的 C# DllImport 没有正确返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 C++ DLL 中有以下函数

I have the following function in a C++ DLL

extern "C" __declspec(dllexport) bool Exist(const char* name)
{
 //if (g_Queues.find(name) != g_Queues.end())
 // return true;
 //else
 // return false;
 return false;
}

在我的 C# 类中,我有以下内容:

Inside my C# class I have the following:

[DllImport("Whisper.dll", EntryPoint="Exist", CallingConvention=CallingConvention.Cdecl)]
        public static extern bool Exist(string name);

然而,每当我调用我的函数时,它总是返回 true,即使我注释掉我的小函数并使其返回 false.我感觉我的调用约定或 P/Invoking 我的 DLL 的任何其他问题有问题,可能与字符串和 const char* 对应,但现在我完全一无所知.我究竟做错了什么?为什么它返回 true 而不是 false?

Yet, whenever I call my function it ALWAYS returns true, even when I commented out my little function and made it return false. I have the feeling there is something wrong with my calling convention or any other issue with P/Invoking my DLL, probably corresponding with the string and const char*, but for now I am completely clueless. What am I doing wrong? Why does it return true instead of false?

我发现这与 const char* 或字符串无关,因为问题仍然存在于空函数中.我尝试更改 Cdecl 和 StdCall 之间的调用约定,但都无法正常工作.我还设法调试了我的 DLL,它被正确调用并且确实返回 false,但是一旦回到 C#,它就以某种方式为真.更改 CharSet 也没有效果.我已经确保每次都为我的 C# 程序提供最新和正确版本的 DLL,所以这也不应该是一个问题.同样,当我实际上返回 false 时,我完全不知道为什么结果是 true.

I have figured out this has nothing to do with the const char* or string, because the problem persists with an empty function. I've tried changing the calling convention between Cdecl and StdCall and neither work correctly. I've also managed to debug my DLL and it's being called correctly and does indeed return false, but once back into C# it somehow is true. Changing the CharSet also had no effect. I've made sure I've supplied my C# program with the latest and correct version of my DLL each time, so that shouldn't be an issue aswell. Again, I am completely clueless on why the result is true when I'm in fact returning false.

SOReader 为我提供了解决另一个重要问题的建议,请参阅我的评论.遗憾的是,它并没有解决退货问题.

SOReader provided me with a suggestion which fixes another important issue, see my comment. Sadly, it does not fix the return issue.

我已经得出结论,将 Exist (bool) 的返回类型更改为 (int) 会突然使其返回正确的数字(true = 1,false =0).这意味着 C++ 的 bool 和 C# 的 bool 之间可能存在问题.我可以继续使用 int 作为 bool,但这仍然不能解释最初的问题.也许其他人可以在这个问题上启发我?也许这与我使用的是 x64 的事实有关(尽管两个项目都编译为 x86)

I have concluded that changing the return type of Exist (bool) into (int) suddenly makes it return the correct number (true = 1, false = 0). That would mean that there may be an issue between C++'s bool and C#'s bool. I can continue using an int as a bool, but that would still not explain the original problem. Maybe somebody else can enlighten me on this one? Perhaps it has to do with the fact that I'm using x64 (although both pojects are compiled as x86)

推荐答案

我找到了解决您问题的方法.您的声明应在此封送处理之前:<代码>[返回:MarshalAs(UnmanagedType.I1)]

I found the solution for your problem. Your declaration should be preceded with this marshaling: [return:MarshalAs(UnmanagedType.I1)]

所以一切都应该是这样的:

so everything should look like this:

[DllImport("Whisper.dll", EntryPoint="Exist", CallingConvention=CallingConvention.Cdecl)]  
[return:MarshalAs(UnmanagedType.I1)]  
public static extern bool Exist([MarshalAs(UnmanagedType.LPStr)] string name);

我在我的一个非常简单的例子中测试了它并且它起作用了!

I tested it in my very simple example and it worked!

编辑
为什么会发生这种情况?C 将 bool 定义为 4 个字节的 int(正如你们中的一些人所说),而 C++ 将其定义为 1 个字节.C# 团队决定在 PInvoke 期间使用 4 字节 bool 作为默认值,因为大多数系统 API 函数使用 4 字节值作为 bool.如果您想更改此行为,您必须通过封送处理指定您要使用 1 字节值.

EDIT
Why this happens? C defines bool as 4 bytes int (as some of you have said) and C++ defines it as 1 byte. C# team decided to use 4 byte bool as default during PInvoke because most of the system API function use 4 bytes values as bool. If you want to change this behavior you have to do it with marshaling specifying that you want to use 1 byte value.

这篇关于带有 C++ 布尔函数的 C# DllImport 没有正确返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆