我在C#dll上创建了一个COM包装器,我在C ++中使用这个COM组件来调用C#dll中的方法。
除非我的C#方法通过COM向C ++返回null,否则一切正常。 在C ++中引发了一个表示
的重复“Debug Assertion失败!” ..... atlsafe.h 235号线 表达式psaSrc!= null。
如何避免此错误并在返回类型中接受空值。
例如。
CComSafeArray itemEntities = objController1-> ListItems(sPath);
当ListItems方法返回null时,系统不应抛出错误。 而itemEntities应该是st到NULL。
请有人建议解决方案。
谢谢, GAGAN
答案 0 :(得分:0)
保留COM中的返回值以将异常传递给不同的模块。要获得实际返回值,可以向函数添加out参数,并将其用作返回值。我认为C#COM Interop已经为你做了这个,但似乎你需要手动完成这个。
答案 1 :(得分:0)
它必须是代码中您未显示的部分。 这对我有用:
C#class:
[ComVisible(true)]
[Guid("BE55747F-FEA9-4C1F-A103-32A00B162DF0")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Test
{
//[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
public string[] GetStringArray()
{
var a = new string[3];
a[0] = "string0";
a[1] = null;
a[2] = "string2";
return a;
}
public string[] GetStringArray2()
{
return null;
}
}
从C ++调用GetStringArray
和GetStringArray2
:
SAFEARRAY* pSA = NULL;
testObject->GetStringArray(&pSA);
printf("str0: %ls\n", ((BSTR*)(pSA->pvData))[0]);
printf("ptr1: %x\n", ((BSTR*)(pSA->pvData))[1]);
printf("str2: %ls\n", ((BSTR*)(pSA->pvData))[2]);
SAFEARRAY* pSA2 = NULL;
testObject->GetStringArray2(&pSA2);
printf("pSA2: %x\n", pSA2);
执行命令
str0: string0
ptr1: 0
str2: string2
pSA2: 0
我没有必要指定如何编组数组(注释掉的行),因为它默认编组为SAFEARRAY(VT_BSTR)
。
已编辑:我想我知道问题出在哪里。您正在使用ATL CComSafeArray
,它不期望设计NULL
SAFEARRAY:
CComSafeArray(_In_ const SAFEARRAY *psaSrc) : m_psa(NULL)
{
ATLASSERT(psaSrc != NULL);
HRESULT hRes = CopyFrom(psaSrc);
if (FAILED(hRes))
AtlThrow(hRes);
}
您应该像这样更改代码:
CComSafeArray<BSTR> itemEntities;
SAFEARRAY* pItemEntities = objController1->ListItems(sPath);
if (NULL != pItemEntities)
itemEntities.Attach(pItemEntities);
或者,直接指定m_psa
:
CComSafeArray<BSTR> itemEntities
itemEntities.m_psa = objController1->ListItems(sPath);
if (!itemEntities)
{
// NULL returned
}