Передача строковых массивов из COM в C # - PullRequest
2 голосов
/ 10 ноября 2011

Мне нужно получить доступ к методам C # в COM dll через COM-подобный интерфейс.Один из методов требует передачи массива строк в качестве входных данных.

Я создаю SAFEARRAY и передаю его в COM Interop.Однако, похоже, это не работает, так как я вижу исключение на уровне взаимодействия.(System.задействовано:

public long DoIt3(int nFiles, string[] fileNames);

Код C ++, вызывающий то же самое:

int _tmain()
{
TCHAR *fileNames[128] = { TEXT("C:\\Program Files\\IBM\\RTC.NET"),
                          TEXT("C:\\KIRAN\\Work\\RFT"), TEXT(".\\bin\\Debug") };

SAFEARRAY *pSA = CreateSafeStringArray(3, fileNames);

_tprintf(TEXT("%d"), pIManaged->DoIt3(3, pSA));

SafeArrayDestroy(pSA);
}

static SAFEARRAY *CreateSafeStringArray(long nElements, TCHAR *elements[])
{
SAFEARRAYBOUND saBound[1];

saBound[0].cElements = nElements;
saBound[0].lLbound = 0;

SAFEARRAY *pSA = SafeArrayCreate(VT_VARIANT, 1, saBound);

if (pSA == NULL)
{
    return NULL;
}

for (int ix = 0; ix < nElements; ix++)
{
    VARIANT v;

    VariantInit(&v);

    v.vt = VT_BSTR;
    v.bstrVal = elements[ix];

    long rgIndicies[1];

    rgIndicies[0] = ix + saBound[0].lLbound;

    HRESULT hr = SafeArrayPutElement(pSA, rgIndicies, &v);

    _tprintf(TEXT("%d"), hr);

    VariantClear(&v);
}

return pSA;
}

Любые идеи / предложения приветствуются.

Ответы [ 2 ]

1 голос
/ 11 ноября 2011

Я понял это!Следующий код работает:

static SAFEARRAY *CreateSafeStringArray(long nElements, TCHAR *elements[])
{
SAFEARRAYBOUND saBound[1];

saBound[0].cElements = nElements;
saBound[0].lLbound = 0;

SAFEARRAY *pSA = SafeArrayCreate(VT_BSTR, 1, saBound);

if (pSA == NULL)
{
    return NULL;
}

for (int ix = 0; ix < nElements; ix++)
{
    BSTR pData = SysAllocString(elements[ix]);

    long rgIndicies[1];

    rgIndicies[0] = saBound[0].lLbound + ix;

    HRESULT hr = SafeArrayPutElement(pSA, rgIndicies, pData);

    _tprintf(TEXT("%d"), hr);
}

return pSA;
}

Спасибо за все ваши предложения!

1 голос
/ 11 ноября 2011

В случае массива строк BSTR вы можете установить значения BSTR непосредственно в вашем массиве, а также вам необходимо выделить память для ваших элементов BSTR , вы можете использовать ATl / MFC CString длячто:

...
psa = SafeArrayCreate( VT_BSTR, 1, saBound);
HRESULT hr = SafeArrayLock( psa );
//TODO: test for hr success

if (pSA == NULL)
{
    return NULL;
}

for (int ix = 0; ix < nElements; ix++)
{
    long rgIndicies[1];
    rgIndicies[0] = ix + saBound[0].lLbound;
    CString tempstr(elements[ix]);

    ((BSTR*)psa->pvData)[ix] = tempstr.AllocSysString();
    _tprintf(TEXT("%d"), hr);
}

hr = SafeArrayUnlock( psa );
//TODO: test for hr success
...
...