从C#编组“as string”参数

时间:2012-05-10 15:36:11

标签: c# string marshalling

进入一个有趣的问题,我想知道是否有人可以帮助解释。我试过在互联网上搜索,似乎无法找到这个问题的答案。虽然我们有一个解决方案,但其他人可能遇到同样的问题,因为它是随机的,所以很难追查。

当计算机连接到客户公司网络时,我们有一个随机失败的应用程序(网络上没有大量信息)。当我们将计算机带到我们的环境中时,它运行良好。失败是相当随机的,但在从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的值非常受控制,在执行此代码之前不为null。

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

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

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

3 个答案:

答案 0 :(得分: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!

答案 1 :(得分:2)

Parameter1.ToString()会将任何.NET对象呈现为字符串(即System.String的实例)。如果Parameter1 as string为空,或者null 不是Parameter1 的实例,System.String将返回null。如果它是一个包装字符串而不是实际 的字符串的类,那么最终会得到一个System.String

当然,两种情况都不适用。如果您的null实例为Parameter1 as string,那么null将正确返回Parameter1.ToString(),而NullReferenceException会抛出Convert.ToString(Parameter1)。< / p>

安全的方法是:{{1}}。

答案 2 :(得分:0)

Parameter1 as string可以被认为是

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

其中.ToString()

string foo = Parameter1.ToString();

参数1不能直接转换为字符串的事实是它失败的共鸣。