方法未返回与 main 中的代码块相同的结果。相同的代码

Method not returning same result as a block of code in main. Identical code

提问人:MatthieuCross 提问时间:8/30/2023 最后编辑:MatthieuCross 更新时间:8/30/2023 访问量:59

问:

我正在制作一个控制台应用程序,它将 c# 中的数据发送并返回到 dll(c++),并返回它。 我让它工作,但遇到了一个我无法理解的问题。

当我在 main 方法中调用代码块时,它可以工作,但是当我创建一个方法(使用相同的代码块)并从 main 方法调用它时,它会中断。我不知道如何更好地解释,所以我会把代码放给你看。

 [DllImport("ActivatorDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
 public static extern IntPtr fullname(byte[] firstname, byte[] lastname);

 static void Main(string[] args) 
 {
     string fn = "Foo";
     string ln = "United";

     IntPtr nameResult  = fullname(Encoding.Default.GetBytes(fn), Encoding.Default.GetBytes(ln));

     
     int len = 0;
     while (Marshal.ReadByte(nameResult, len) != 0) ++len;
     byte[] buffer = new byte[len];
     Marshal.Copy(nameResult, buffer, 0, buffer.Length);
     string res = Encoding.Default.GetString(buffer);

     string res2 = StringFromNative(nameResult);

     Console.WriteLine(res);
     Console.WriteLine(res2);

     Console.ReadLine();
 }

 public static string StringFromNative(IntPtr native)
 {
     int len = 0;
     while (Marshal.ReadByte(native, len) != 0) ++len;
     byte[] buffer = new byte[len];
     Marshal.Copy(native, buffer, 0, buffer.Length);
     return Encoding.Default.GetString(buffer);
 }

RES 正在按预期工作。但是 RES2 不起作用

result

谢谢!

我尝试在这里和其他平台上寻找解决方案或解释,但在任何地方都得不到答案。

DLL 的 CPP 中的 fullName 函数

char* fullname(char* firstname, char* lastname)
{
    char result[1000] = ""; 
    strcpy_s(result, firstname);
    strcat_s(result, " ");
    strcat_s(result, lastname);
    
    return result;
}
C# 方法 封送 intptr

评论

0赞 Kabilu 8/30/2023
我认为您错过了静态函数中的“DllImport”。尝试将“DllImport”放在上面的静态函数中。
2赞 clausc 8/30/2023
在不知道C++ dll中的实现的情况下,很难确定,但我的猜测是结果已被取消分配。事实上,第一次调用成功可能是一个小小的奇迹。内存是如何分配的?
0赞 Jean-Baptiste Yunès 8/30/2023
什么功能?缺少其代码。fullname
0赞 Charlieface 8/30/2023
事实上,你的C++代码是错误的。它在堆栈上分配,然后转储堆栈。相反,您应该从 C# 传入一个缓冲区,然后填充该缓冲区。此外,您无需手动将其编组为单位,只需在它们之间传递或传递即可。为什么需要这个 C++ 函数?resultstringStringBuilder
1赞 Charlieface 8/30/2023
因此,您需要一个 C++ 函数,该函数返回已设置的字节数,然后在 C# 中将其定义为并创建一个足够大小的缓冲区并将其传入。int fullname(const char* firstname, const char* lastname, char* buffer, int bufferSize).... CharSet.Ansi)] public static extern int fullname(string firstname, string lastname, StringBuilder buffer, int bufferSize);StringBuilder

答: 暂无答案