所以我有一个用于excel的VSTO插件,我想调用我编写的代码,利用一些自动化。我在c ++中使用导入的lib文件方法编写了这里:
C++ app automates Excel (CppAutomateExcel)
所以我有一个扩展方法:
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对象。没有简洁的方法可以从中获取指针。
我尝试了此处描述的方法:C# - How To Convert Object To IntPtr And Back?
但是创建工作簿的GCHandle会在alloc调用上崩溃。
如果我只是传递对象原始的东西似乎工作,直到我关闭时,我得到一个rpc服务器不可用错误
我将pinvoke更改为
#region IsEmbeded
[DllImport("test.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern bool IsEmbeded([MarshalAs(UnmanagedType.IUnknown)] object Book);
#endregion
事情似乎正在起作用......但现在关机时的RPC错误是不确定的。
有没有办法去除远程可调用包装器.net封装所有这些com对象并只传递原始指针?有谁知道我怎么能这样做?