我正在尝试使用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#函数声明有问题吗?
1条答案
按热度按时间rkue9o1l1#
信不信由你,第一个问题是由bool返回类型引起的。我的理论是,一个字节的bool和一个4字节的int之间的差异会造成堆栈问题,我的
LPUTF8Str
指针是垃圾。我将返回类型更改为int,登录成功。第二个问题显然是由于在我试图创建的会话对象的构造函数中调用Login函数引起的。我知道这是一个不确定的命题,但我正在构建一个简单的测试应用程序,并认为我可以摆脱它。