Типы двойных указателей в C ++ / CLI для ссылки на IntPtr для доступа к C # - PullRequest
2 голосов
/ 25 июля 2011

Я пишу оболочку для C DLL в C ++ / CLI, чтобы к ней можно было получить доступ в C # через управляемую сборку.Использование прямого P / Invoke для доступа к функциям C через C # невозможно, поскольку C DLL вызывает исключения, которые невозможно правильно отловить с помощью P / Invoke (сообщение об исключении теряется при перемещении через границу C / C #).Таким образом, идея состоит в том, чтобы создать управляемую DLL CLI, которая внутренне вызывает C DLL и переносит исключение в класс исключения CLI.

Таким образом, функция DLL C имеет это объявление.

void InitDB(void **handle);

Приложению C # потребуется следующее объявление

void InitDB_cs(ref IntPtr handle);

Для этого я создал функцию C ++ / CLI сследующее объявление

void InitDB_clr(IntPtr %handle);

Однако я не могу вписать ref InPtr в функцию C.Я попытался использовать следующий код, но, похоже, не смог правильно настроить тип.

void InitDB_clr(IntPtr %handle)
{
pin_ptr<IntPtr> ptr = handle.ToPointer();
InitDB(&ptr);
}

Сообщение об ошибке для кода выше

error C2440: 'initializing' : cannot convert from 'void *' to 'cli::pin_ptr<Type>'
1>        with
1>        [
1>            Type=System::IntPtr
1>        ]
1>        Conversion from 'void*' to pointer to non-'void' requires an explicit cast
1>error C2664: 'InitDB' : cannot convert parameter 1 from 'cli::pin_ptr<Type> *' to 'void **'
1>        with
1>        [
1>            Type=System::IntPtr
1>        ]
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Ответы [ 2 ]

1 голос
/ 25 июля 2011

Это out параметр, не совсем ref, верно?

Попробуйте

void InitDB_clr(IntPtr% handle)
{
    void* ptr /* = handle.ToPointer() */;
    InitDB(&ptr);
    handle = IntPtr(ptr);
}

Раскомментируйте инициализатор, если он должен быть включен / выключен.

0 голосов
/ 25 июля 2011

Вы можете использовать C # в небезопасном контексте и использовать

unsafe void InitDB_cs(IntPtr** handle);
...