Как вернуть умный указатель C ++ в интерфейс PowerPoint, используя интерфейс C #

Я делаю программу, частично написанную на C ++ и C #.
C # в основном используется для графического интерфейса.
Внутри своего кода C ++ я создаю объект PowerPoint COM и открываю в нем презентацию.

В какой-то момент мне нужно ссылаться PowerPoint::_PresentationPtr в моем коде C #. Для вызова методов и так далее.

PowerPoint::_PresentationPtr это умный указатель, сделанный с

_COM_SMARTPTR_TYPEDEF(_Presentation, __uuidof(_Presentation));

Определяется Visual studio в msppt.tlh Microsoft.Office.Interop.PowerPoint.dll связывание:

struct __declspec(uuid("91493463-5a91-11cf-8700-00aa0060263b"))
/* interface */ PresEvents;
struct /* coclass */ Presentation;

struct __declspec(uuid("9149349d-5a91-11cf-8700-00aa0060263b"))
/* dual interface */ _Presentation;

/* PowerPoint::_PresentationPtr */
_COM_SMARTPTR_TYPEDEF(_Presentation, __uuidof(_Presentation));

Так что это делает PowerPoint::_PresentationPtr для простоты использования COM-объекта в C ++, вызова методов и т. д.

И это C # Microsoft.Office.Interop.PowerPoint.Presentation

namespace Microsoft.Office.Interop.PowerPoint
{
[CoClass(typeof(PresentationClass))]
[Guid("9149349D-5A91-11CF-8700-00AA0060263B")]
public interface Presentation : _Presentation, PresEvents_Event
{
}
}

У меня есть интерфейс в C # с реализацией C ++, поэтому я могу получить к нему доступ в C # части приложения.

ApplicationHost.cs

namespace SampleWpfUserControlLibrary
{
public interface IApplicationHostWindow
{
void OpenDocument();
PowerPoint.Presentation GetPresentation();
void Exit();
}
}

ApplicastionHost.h

#pragma once
#using <SampleWpfUserControlLibrary.dll>

using namespace SampleWpfUserControlLibrary;

ref class ApplicationHostWrapper : IApplicationHostWindow
{
public:
ApplicationHostWrapper(CMainFrame * pMainFrame)
{
_pMainFrame = pMainFrame;
}

virtual void __clrcall Exit() sealed
{
_pMainFrame->SendMessage(WM_CLOSE);
}

virtual void __clrcall OpenDocument() sealed
{
_pMainFrame->OpenDocument();
}

virtual PowerPoint::_PresentationPtr __clrcall GetPresentation() sealed
{
CMFCBindDoc * pDoc = _pMainFrame->GetDocView()->GetDocument();
return pDoc->GetPresentation();
}
};

Однако это не компилируется. Утверждая, что GetPresentation() не реализовано.
Как типы не совпадают.

Обновить:

Что я должен вернуть в C ++ код PowerPoint::_Presentation или же PowerPoint::_PresentationPtr и что я должен сопоставить это в C # части? Или как преобразовать его в Microsoft.Office.Interop.PowerPoint в C #? Я просто хочу сослаться на это в C #.

Вот ошибки, которые я получаю: **

  • Ошибка 3, ошибка C2259: «ApplicationHostWrapper»: невозможно создать экземпляр абстрактного класса
    Source \ Application \ MainFrm.cpp 146 1 Приложение
  • Ошибка 1, ошибка C3766: ApplicationHostWrapper должен предоставить реализацию метода интерфейса
    «Microsoft :: Офис :: Interop :: PowerPoint :: Презентация
    ^ SampleWpfUserControlLibrary :: IApplicationHostWindow :: getPresentation (void) ‘source \ application \ ApplicationHostWrapper.h 39 1 Приложение

В Object Browser метод getPresentation () выглядит так:

неизвестный тип ^ getPresentation ()
Член SampleWpfUserControlLibrary :: IApplicationHostWindow

2

Решение

Хорошо, я нашел решение.
в ref class ApplicationHostWrapper : IApplicationHostWindow вызывая GetInterfacePtr () для умного указателя, мы можем получить указатель на интерфейс.

virtual void* __clrcall GetPresentationPtr() sealed
{
CMFCBindDoc * pDoc = _pMainFrame->GetDocView()->GetDocument();
return (void*)pDoc->GetPresentation().GetInterfacePtr();
}

В объявлении интерфейса C # ApplicationHost.cs:

namespace SampleWpfUserControlLibrary
{
public interface IApplicationHostWindow
{
void OpenDocument();
unsafe void* GetPresentationPtr();
void Exit();
}
}

И это позволяет нам создать метод в управляемом коде, например, в классе:

private IApplicationHostWindow _hostWindow;
unsafe private PowerPoint.Presentation getPresentation(){
IntPtr preIntPtr = new IntPtr(_hostWindow.GetPresentationPtr());
return (PowerPoint.Presentation)Marshal.GetUniqueObjectForIUnknown(preIntPtr);
}

Единственным недостатком является то, что он требует использования / unsafe для компиляции. И какие могут быть последствия я пока не представляю. Если кто-то знает, как преодолеть / сделать небезопасным и сделать это по-другому, милости просим.

1

Другие решения


По вопросам рекламы [email protected]