2013-08-31 1 views
1

Я создал оболочку COM поверх dll dll, и я использую этот компонент COM в C++ для вызова методов в C# dll.Выброс ненулевого возвращаемого значения Исключение в COM-клиенте, написанное на C++

Все работает нормально, за исключением случаев, когда мой метод C# возвращает значение null через COM на C++. Экспрессия брошена на C++, что говорит

«Уступка отладки не удалась!» ..... atlsafe.h Линия 235 Выражение psaSrc! = null.

Как избежать этой ошибки и принять нулевое значение в возвращаемом типе.

например.

CComSafeArray itemEntities = objController1-> ListItems (sPath);

Когда метод ListItems возвращает значение null, система не должна вызывать ошибку. Вместо itemEntities должно быть st до NULL.

Пожалуйста, предложите какое-либо решение.

Спасибо, Gagan

+0

null = '\ 0', NULL - это способ ANSI объявления указателя, который, как известно, недействителен. NULL - это макрос, определенный в Попробуйте #define null NULL в ur C++ cpp – Abhineet

+0

#define null NULL did not work – Gags

+0

Я не знаю точного ответа.Первый взгляд на ваш вопрос дал мне эту идею, поскольку 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; 
    } 
} 

Вызов GetStringArray и GetStringArray2 от C++:

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).

EDITED: Думаю, я вижу, где проблема. Вы используете 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

Это работало для meCComSafeArray itemEntities; SAFEARRAY * pItemEntities = objController1-> ListItems (sPath); if (NULL! = PItemEntities) itemEntities.Attach (pItemEntities); – Gags

0

Возвращаемое значение в COM зарезервирован для передачи исключения различных модулей. Чтобы получить реальное возвращаемое значение, вы можете добавить параметр out к своей функции и использовать его как возвращаемое значение. Я думал, что C# COM Interop уже сделает это за вас, но кажется, что вам нужно сделать это вручную.

 Смежные вопросы

  • Нет связанных вопросов^_^