5

遇到一个有趣的问题,我想知道是否有人可以帮助解释。我已经尝试在整个互联网上搜索,但似乎无法找到这个问题的答案。虽然我们有解决方案,但其他人可能会遇到同样的问题,而且由于它是随机的,因此很难追踪。

我们有一个应用程序在计算机连接到客户公司网络时随机失败(网络上没有很多信息)。当我们将计算机带到我们的环境中时,它运行良好。失败是相当随机的,但据我所知,这是在从 C# 调用非托管第三方供应商 DLL 期间发生的。我确实有一个回溯(只有几个失败在系统事件日志中提供了跟踪)指向在对非托管 DLL 的调用进行参数编组期间 RtlMoveMemory 函数中的 ntdll.dll 中的故障。

对非托管函数的调用是:

ThirdParty.CxxxAutomationWrapper clientDLL = new ThirdParty.CxxxAutomationWrapper () ;

object Parameter1 ;
  :
string theValue = "abcde" ;
Parameter1 = theValue ;
  :
if ( Parameter1 is string )
{
    int returnCode = clientDLL.function ( Parameter1 as string ) ;
}

该调用在客户计算机上定期失败,但在 Visual Studio (2010) 中运行时始终有效。Parameter1 的值设置正确(从不为空)。

由于我将呼叫更改为:

String parameter1String = Parameter1.ToString() ;
int returnCode = clientDLL.function ( parameter1String ) ;

一切正常。Parameter1 的值非常受控制,在执行此代码之前不为空。

被调用的接口(clientDLL.function)定义为:

HRESULT function ( [in] BSTR parameter,
                   [out, retval] long *ret);

由于我对 c# 中的“as”语句的 [有限?] 理解,我不明白为什么第一个版本失败了。任何人都可以帮助解释为什么在使用指定为“as string”的参数调用时会失败吗?

4

3 回答 3

5

因为obj as stringobj.ToString()不一样。第一个是尝试的强制转换(有点像(string)obj,但null在失败时返回),而第二个是返回对象的字符串表示的方法调用。

实际上,您可以获得任何对象的字符串表示形式,无论它是否与作为类型的字符串兼容,但如果它们不兼容,则转换将失败。

简单的例子:

object obj = new object(); // simple object
Console.WriteLine(obj.ToString()); // prints System.Object
Console.WriteLine((obj as string) == null); // True: obj is not a string!
于 2012-05-10T15:38:28.203 回答
2

Parameter1.ToString()将任何 .NET 对象呈现为字符串(即 的实例System.String)。如果为 nullParameter1 as string不是. 如果它是一个包装字符串的类而不是一个真正的类那么你最终会得到一个.nullParameter1System.Stringnull

当然,两者都不会在每种情况下都起作用。如果您有System.Stringis的实例nullParameter1 as string则将正确返回null,而Parameter1.ToString()将抛出NullReferenceException.

一种安全的方法是:Convert.ToString(Parameter1).

于 2012-05-10T15:39:16.487 回答
0

Parameter1 as string可以认为是

string foo
try
{
    foo = (string)Parameter1;
}
catch
{
    foo = null;
}

.ToString()在哪里

string foo = Parameter1.ToString();

Parameter1 不能直接转换为字符串的事实是它失败的原因。

于 2012-05-10T15:44:56.173 回答