Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#如何将Excel.workbook转换为IntPtr以传递给导出的dll函数_C#_C++_.net_Excel_Com - Fatal编程技术网

C#如何将Excel.workbook转换为IntPtr以传递给导出的dll函数

C#如何将Excel.workbook转换为IntPtr以传递给导出的dll函数,c#,c++,.net,excel,com,C#,C++,.net,Excel,Com,因此,我有一个用于excel的VSTO加载项,我想调用我利用自动化编写的代码。在C++中,我使用了这里指定的LIB文件方法: 所以我有一个扩展方法: public static bool isEmbeded(this Excel.Workbook Book) { return dllFuncs.IsEmbeded(Book); } 和一个dll导入函数: namespace dllFuncs { #region IsEmbeded [DllIm

因此,我有一个用于excel的VSTO加载项,我想调用我利用自动化编写的代码。在C++中,我使用了这里指定的LIB文件方法:

所以我有一个扩展方法:

public static bool isEmbeded(this Excel.Workbook Book)
    {
        return dllFuncs.IsEmbeded(Book);
    }
和一个dll导入函数:

namespace dllFuncs
{
    #region IsEmbeded
    [DllImport("test.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
    public static extern bool IsEmbeded(Excel.Workbook Book);
    #endregion
}
它对应于一个导出函数,该函数接受一个
IUnknown
指针,并在其上执行一个查询接口,以确定它是excel工作簿、word文档还是powerpoint演示文稿

c++代码头:

bool WINAPI IsEmbeded(IUnknown* pOfficeDocument);

class EmbededHelperFunctions
{
public:
    static bool isEmbeded(IUnknown* pOfficeDocument);
private:
    static bool isEmbededHelper(IUnknown* pOfficeDocument);
    EmbededHelperFunctions() = delete;
}
c++cpp代码:

bool WINAPI IsEmbeded(IUnknown* pOfficeDocument)
{
    return EmbededHelperFunctions::isEmbeded(pOfficeDocument);
}

bool EmbededHelperFunctions::isEmbededHelper(IUnknown* pOfficeDocument)
{
    Excel::_WorkbookPtr spXlBook = nullptr;
    HRESULT  hResult = pOfficeDocument->QueryInterface(&spXlBook);

    if(hResult == S_OK)
    {
        _bstr_t path = spXlBook->Path;

        return (path.GetAddress() == nullptr || path.length() == 0);
    }

    return false;
}

bool EmbededHelperFunctions::isEmbeded(IUnknown* pOfficeDocument)
{
    if (isEmbededHelper(pOfficeDocument))
    {
        IOleObject *LobjOleObject = nullptr;
        IOleClientSite *LobjPpClientSite = nullptr;
        if (pOfficeDocument->QueryInterface(&LobjOleObject) == S_OK)
        {
            // get the client site
            LobjOleObject->GetClientSite(&LobjPpClientSite);

            if (LobjPpClientSite != nullptr)
            {
                // if there is one - we are embedded
                return true;
            }
        }
    }

    // not embedded
    return false;
}
现在我遇到的第一个问题是尽管工作簿是COM对象。没有简单的方法可以从中获取指针

我尝试了这里描述的方法:

但是创建工作簿的GCHandle在alloc调用时崩溃

如果我只是传递对象原始的东西似乎工作,直到我关机时,我得到一个rpc服务器是不可用的错误

我把平沃克换成了

#region IsEmbeded
        [DllImport("test.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern bool IsEmbeded([MarshalAs(UnmanagedType.IUnknown)] object Book);
#endregion
事情似乎又开始起作用了。。。但是现在关闭时的RPC错误是不确定的


有没有办法去掉.net封装所有这些com对象的远程可调用包装器,只传递原始指针?有人知道我是怎么做到的吗?

你有没有试过把
Excel.Workbook
作为p/调用的对象传入?@ScottChamberlain我试过了,它没有崩溃,但当我在非托管代码中对它执行QI时,它不会被识别为Excel::Workbook类型。我刚刚发布了代码。你看到我的帮助码有什么不对吗?我不知道足够的C++在这个级别上有多大的帮助。@斯科特·伯恩:好吧,那么C语言上的PUNKEK会出错吗?我没有指定如何整理工作簿。