首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当尝试获取类方法指针时,E_NOINTERFACE

当尝试获取类方法指针时,E_NOINTERFACE
EN

Stack Overflow用户
提问于 2012-09-15 10:50:57
回答 1查看 720关注 0票数 3

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

我把代码简化了一点

这是一个有问题的方法。

代码语言:javascript
复制
    [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
    public ScOrder[] GetOrders()
    {
        return new ScOrder[] {

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

这是IScOrder接口

代码语言:javascript
复制
[ComVisible(true)]
[Guid("B2B134CC-70A6-43CD-9E1E-B3A3D9992C3E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IScOrder
{
    long GetQuantity();
}

这是ScOrder实现

代码语言:javascript
复制
[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的帮助后。这个问题在评论中描述了。

  • 我不使用ATL和MFC。
  • C++ tlb文件是通过regasm生成的。

COM初始化和调用GetOrders方法运行良好

代码语言:javascript
复制
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(朋克)中调试:

代码语言:javascript
复制
IScOrderPtr order(punk);

所以我走上了秩序(朋克),看看那里发生了什么。我进了一家“公司”

代码语言:javascript
复制
// 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);

...then I进入了_QueryInterface(p)实现,也是在comip.h中

代码语言:javascript
复制
// 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 expert...please帮助:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-15 11:07:52

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

它应该是:

代码语言:javascript
复制
//[ComVisible(true)]
//[Guid("F739759E-4D00-440E-B0B7-69AAF97FCB6D")]
//[ClassInterface(ClassInterfaceType.None)]
public class ScOrder : IScOrder

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

在不继承IScOrder的情况下,您的实例确实有一些接口,但是您感兴趣的IScOrder确实无法在指针上访问。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12436742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档