C#DllImport与C ++布尔函数无法正确返回 [英] C# DllImport with C++ boolean function not returning correctly

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

问题描述

我在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 /调用我的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 *或string,因为问题仍然存在一个空的函数。我试过改变Cdecl和StdCall之间的调用约定,并且都不能正常工作。我也设法调试我的DLL,它被正确调用,确实返回false,但是一旦回到C#,它就是真的。改变CharSet也没有效果。我已经确保我每次都提供我的C#程序,最新和正确的DLL版本,所以这不应该是一个问题。再次,我完全无知,为什么当我实际上返回错误时,结果是真实的。

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.

EDIT2: SOReader提供了一个修正另一个重要问题的建议,看我的评论。不幸的是,它并不能解决退货问题。

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

EDIT3: Exist(bool)into(int)突然使它返回正确的数字(true = 1,false = 0)。这意味着C ++的bool和C#的bool之间可能存在一个问题。我可以继续使用int作为bool,但这仍然不能解释原来的问题。也许其他人可以启发我这个?也许这与我使用x64的事实有关(虽然两个pojects被编译为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)

推荐答案

我发现解决你的问题。您的声明应在此封送之前:
[return: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#DllImport与C ++布尔函数无法正确返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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