如何使用c#接口返回c++智能指针到PowerPoint界面

How to return C++ smart pointer to PowerPoint interface using C# Interface

本文关键字:指针 PowerPoint 界面 智能 c++ 何使用 接口 返回      更新时间:2023-10-16

我正在制作一个部分用c++和c#编写的程序。c#主要用于GUI。在我的c++代码中,我创建了一个PowerPoint COM对象并在其中打开一个演示文稿。

在某些时候,我需要在我的c#代码中引用PowerPoint::_PresentationPtr。调用方法等等。

PowerPoint::_PresentationPtr是用

做成的智能指针
_COM_SMARTPTR_TYPEDEF(_Presentation, __uuidof(_Presentation));

由Visual studio在msppt中定义。tlh Microsoft.Office.Interop.PowerPoint.dll binding:

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便于在c++中使用COM对象,调用方法等

这是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::_PresentationPowerPoint::_PresentationPtr和我应该映射到c#部分?或者如何在c#中转换成Microsoft.Office.Interop.PowerPoint ?我只是想在c#中引用它。

我得到的错误如下:**

  • 错误3错误C2259: 'ApplicationHostWrapper':不能实例化抽象类
    SourceApplicationMainFrm.cpp 146 1 Application
  • 错误1错误C3766: 'ApplicationHostWrapper'必须提供接口方法的实现
    微软::::互操作::幻灯片::表示
    ^SampleWpfUserControlLibrary::IApplicationHostWindow::getPresentation(void)' sourceapplicationApplicationHostWrapper.h 39 1 application

在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进行编译。我还不知道后果会是什么。如果有人知道如何克服/不安全,并以不同的方式来做,欢迎你。