2013-08-31 62 views
1

我已經通過C#dll做了一個COM包裝器,並且我在C++中使用這個COM組件來調用C#dll中的方法。在C++中編寫的COM客戶端中拋出異常返回值異常

所有工作正常,除非我的C#方法通過COM到C++返回null。 在C++中拋出了一個缺陷,說

「Debug Assertion failed!」 ..... atlsafe.h行235 表達式psaSrc!= null。

如何避免此錯誤並在返回類型中接受空值。

例如。

CComSafeArray itemEntities = objController1-> ListItems(sPath);

當ListItems方法返回null時,系統不應該拋出錯誤。 相反,itemEntities應該st爲NULL。

請有人提出一個解決方案。

謝謝, 加甘

+0

null ='\ 0',NULL是ANSI聲明已知無效指針的方式。 NULL是在烏拉圭回合C++ CPP – Abhineet

+0

的#define空NULL沒有工作 – Gags

+0

我不知道確切的答案 嘗試的#define空NULL定義的宏。你的問題的第一個看法給了我這個想法,因爲NULL通常用於檢查指針,而「null」就是char'\ 0'。 – Abhineet

回答

0

它必須是代碼中沒有顯示的部分。 這個工作對我來說:

C#類:

[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中調用GetStringArrayGetStringArray2 ++:

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 

我沒有指定如何編組數組(註釋掉的行),因爲我t默認爲編號爲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 
} 
+1

這對我有效CComSafeArray itemEntities; SAFEARRAY * pItemEntities = objController1-> ListItems(sPath);如果(NULL!= pItemEntities) itemEntities.Attach(pItemEntities); – Gags

0

在COM的返回值被保留以通過例外不同的模塊。爲了得到一個真正的返回值,你可以添加一個out參數給你的函數,並用它作爲返回值。我以爲C#COM Interop已經爲你做了這個,但是你似乎需要手動完成。