.net P/Invoke UTF-8字符串未正确传递并损坏堆

hlswsv35  于 2023-05-30  发布在  .NET
关注(0)|答案(1)|浏览(115)

我正在尝试使用P/Invoke在.Net Framework应用程序中使用C dll。下面是C源代码中声明的函数签名:

/* extern "C" */ __declspec(dllimport) int __stdcall Login(void* handle, 
          const char* username, 
          const char* password, 
          const char* code, 
          const char* appID, 
          const char* cache_path );

dll的提供者告诉我,API中使用的所有字符串都是UTF-8编码的。考虑到这些信息,下面是我对C#等价物的尝试:

[DllImport("MY_API.dll")]
protected static extern bool Login(IntPtr handle,
    [MarshalAs(UnmanagedType.LPUTF8Str)] string username,
    [MarshalAs(UnmanagedType.LPUTF8Str)] string password,
    [MarshalAs(UnmanagedType.LPUTF8Str)] string code,
    [MarshalAs(UnmanagedType.LPUTF8Str)] string appID,
    [MarshalAs(UnmanagedType.LPUTF8Str)] string cacheDataPath);

handle参数是一个void*值,我从另一个dll调用中收到。我能够在其他dll调用中使用IntPtr,并得到了我期望的结果。我已经验证了我正在使用dll供应商提供的命令行演示应用程序传递正确的用户名和密码。但是当我从.Net应用程序调用这个函数时,会发生两件事:
1.返回值表明我的用户名或密码错误。
1.在函数调用后不久,我的应用程序关闭,返回一个代码,指示堆已损坏。
我也试过使用UnmanagedType.LPStr,但结果相同。
不幸的是,dll的提供者不熟悉C#/.Net,并且不能提供任何关于这里发生的事情的见解。
我的C#函数声明有问题吗?

rkue9o1l

rkue9o1l1#

信不信由你,第一个问题是由bool返回类型引起的。我的理论是,一个字节的bool和一个4字节的int之间的差异会造成堆栈问题,我的LPUTF8Str指针是垃圾。我将返回类型更改为int,登录成功。
第二个问题显然是由于在我试图创建的会话对象的构造函数中调用Login函数引起的。我知道这是一个不确定的命题,但我正在构建一个简单的测试应用程序,并认为我可以摆脱它。

相关问题