gpt4 book ai didi

c# - E_NOINTERFACE 尝试获取类方法指针时

转载 作者:太空狗 更新时间:2023-10-29 23:07:34 26 4
gpt4 key购买 nike

我正在从 C++ 非托管代码调用 C# 方法。我在从数组中返回的类实例获取值时遇到问题。

我稍微简化了代码

这是有问题的方法。

    [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
public ScOrder[] GetOrders()
{
return new ScOrder[] {

(new ScOrder(1),
(new ScOrder(2)
};
}

这是 IScOrder 接口(interface)

[ComVisible(true)]
[Guid("B2B134CC-70A6-43CD-9E1E-B3A3D9992C3E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IScOrder
{
long GetQuantity();
}

这是 ScOrder 的实现

[ComVisible(true)]
[Guid("F739759E-4D00-440E-B0B7-69AAF97FCB6D")]
[ClassInterface(ClassInterfaceType.None)]
public class ScOrder
{
private long quantity = 0;

public ScOrder() {}

public ScOrder(long quantity)
{
this.quantity = quantity;
}

public long GetQuantity()
{
return this.quantity;
}
}

这是 C++ 代码,在我的 previous request 中得到 Zdeslav Vojkovic 的帮助之后.问题在评论中描述

  • 我没有使用 ATL 或 MFC。
  • C++ tlb 文件是通过 regasm 生成的。

COM 初始化和调用 GetOrders 方法效果很好

IScProxyPtr iPtr;
CoInitialize(NULL);
iPtr.CreateInstance(CLSID_ScProxy);
SAFEARRAY* orders;
iPtr->GetOrders(&orders);
LPUNKNOWN* punks;
HRESULT hr = SafeArrayAccessData(orders, (void**)&punks);
if(SUCCEEDED(hr))
{
long lbound, ubound;
SafeArrayGetLBound(orders, 1, &lbound);
SafeArrayGetUBound(orders, 1, &ubound);
long elements = ubound - lbound + 1;
for(int i=0;i<elements;i++)
{
LPUNKNOWN punk = punks[i]; //the punk seems valid
IScOrderPtr order(punk); //unfortunatelly, "order" now points to {0x00000000}

//subsequent attempt to get the value will fail
long quantity = 0;
HRESULT procCall;
//GetQuantity will throw an exception
procCall = order->GetQuantity((long long *)q);

}
SafeArrayUnaccessData(orders);
}
SafeArrayDestroy(orders);

感谢 Zdeslav,我发现我可以在 order(punk) 内部进行调试:

IScOrderPtr order(punk);

所以我走进 order(punk) 看看那里发生了什么。我进入了“comip.h”

// Constructs a smart-pointer from any IUnknown-based interface pointer.
//
template<typename _InterfaceType> _com_ptr_t(_InterfaceType* p)
: m_pInterface(NULL)
{
HRESULT hr = _QueryInterface(p);

...然后我进入 _QueryInterface(p) 实现,也在 comip.h 中

// Performs a QI on pUnknown for the interface type returned
// for this class. The interface is stored. If pUnknown is
// NULL, or the QI fails, E_NOINTERFACE is returned and
// _pInterface is set to NULL.
//
template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw()
{
HRESULT hr;

// Can't QI NULL
//
if (p != NULL) {
// Query for this interface
//
Interface* pInterface;
hr = p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface));

现在这里的问题是返回的“hr”的值是 E_NOINTERFACE ...这是不对的。

我不是 C++ 或 COM 专家...请帮忙 :)

最佳答案

您的类 ScOrder 似乎没有在 C# 端实现 IScOrder 接口(interface)。

应该是:

//[ComVisible(true)]
//[Guid("F739759E-4D00-440E-B0B7-69AAF97FCB6D")]
//[ClassInterface(ClassInterfaceType.None)]
public class ScOrder : IScOrder

我在上面评论 [...] 不是因为它在干扰,而是因为它看起来没有必要:它是 IScOrder 需要具有 COM 可见性并且应该是能够在 C++ 端获得它。

如果不继承 IScOrder,您的实例确实有一些接口(interface),但您感兴趣的 IScOrder 确实无法通过指针访问。

关于c# - E_NOINTERFACE 尝试获取类方法指针时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12436742/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com