Я делаю программу, частично написанную на 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
Хорошо, я нашел решение.
в 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 для компиляции. И какие могут быть последствия я пока не представляю. Если кто-то знает, как преодолеть / сделать небезопасным и сделать это по-другому, милости просим.