Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.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# 试图获取类方法指针时,E_没有接口 < >我从C++非托管代码中调用Cyz方法。我在从数组中返回的类实例获取值时遇到问题_C#_C++_Com_Safearray_Queryinterface - Fatal编程技术网

C# 试图获取类方法指针时,E_没有接口 < >我从C++非托管代码中调用Cyz方法。我在从数组中返回的类实例获取值时遇到问题

C# 试图获取类方法指针时,E_没有接口 < >我从C++非托管代码中调用Cyz方法。我在从数组中返回的类实例获取值时遇到问题,c#,c++,com,safearray,queryinterface,C#,C++,Com,Safearray,Queryinterface,我把代码简化了一点 这是有问题的方法 [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)] public ScOrder[] GetOrders() { return new ScOrder[] { (new ScOrder(1), (new ScOrder(2) };

我把代码简化了一点

这是有问题的方法

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

            (new ScOrder(1),
            (new ScOrder(2)
        };
    }
这是IScOrder接口

[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++代码,在Zdeslav Vojkovic的帮助下。注释中描述了该问题

  • 我没有使用ATL或MFC
  • 通过ReaSim.
  • 生成C++ TLB文件。
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&lt;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,我发现我可以在订单内部调试(朋克):

所以我进入秩序(朋克)去看看那里发生了什么。我进了一个“comip.h”

//从任何基于IUnknown的接口指针构造智能指针。
//
模板(接口类型*p)
:m_pInterface(空)
{
HRESULT hr=_查询接口(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));
//对返回的接口类型执行QI
//对于此类。存储接口。如果已知
//NULL,或QI失败,返回E_NOINTERFACE并
//\u pInterface设置为空。
//
模板HRESULT_QueryInterface(_interfaceptrp)throw()
{
HRESULT-hr;
//不能是空的吗
//
如果(p!=NULL){
//查询此接口
//
接口*pInterface;
hr=p->QueryInterface(GetIID(),重新解释强制转换(&pinInterface));
现在这里的问题是返回的“hr”值是E_NOINTERFACE…这是不对的


<>我不是C++或COM专家…请帮助:

< P>你的类<代码> Buffer-<代码>似乎在C端不执行代码> ISCORDER < /代码>接口。< /P> 应该是:

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

我评论了<代码>……>代码>不是因为它是干扰的,而是因为它看起来不需要:它是代码> ISCORDER < /Cord>需要COM可见性,并且应该能够在C++端获得它。


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

再次,StackOverflow中的人证明我是一个瞎子。我只想调试一下,看看这是否有效,然后接受这个答案。出于某种原因,GetQuantity返回0,但这是另一个问题。谢谢:)
E_NOINTERFACE
在这里是一个很好的提示。您确实有一些对象,并且您知道它是您的order类。但是它没有提供您需要的接口,所以它只是一个关于接口可见性的问题。
procCall
预期为零(
s_OK
).
quantity
可能保持为零,因为您提供了
&q
作为参数,而不是
&quantity
:)
// 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));
//[ComVisible(true)]
//[Guid("F739759E-4D00-440E-B0B7-69AAF97FCB6D")]
//[ClassInterface(ClassInterfaceType.None)]
public class ScOrder : IScOrder