C++ 비 관리 코드에서 C# 메서드를 호출하고 있습니다. 배열에서 반환 된 클래스 인스턴스에서 값을 가져 오는 데 문제가 있습니다.E_NOINTERFACE 클래스 메서드 포인터를 가져 오는 중
나는이 문제가있는 방법입니다 코드를 조금
을 단순화했습니다.
[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();
}
입니다 그리고 이것은 내 previous request에서 Zdeslav Vojkovic에서 도움이 후 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++ 코드입니다. 문제는 설명에 설명되어 있습니다.
- ATL도 MFC도 사용하고 있지 않습니다.
- C++ tlb 파일은 regasm을 통해 생성됩니다.
COM 초기화와 GetOrders를 호출하는 방법은 내가 순서 내부 (펑크)를 디버깅 할 수 있다는 것을 발견, Zdeslav 좋은
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);
감사를 작동합니다
IScOrderPtr 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);
내부에있어 ... 나는 또한 comip.h에서 _QueryInterface (p)를 구현 내부 계단
// 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# 측 IScOrder
인터페이스를 구현하지 않는 것 :
다시 말하지만, 나는 StackOverflow에있는 사람들에 의해 눈먼 바보로 판명났습니다. 이 문제를 디버그하여 작동하는지 확인한 다음이를 대답으로 받아 들일 것입니다. – Mirek
어떤 이유로 GetQuantity는 0을 반환하지만 다른 문제입니다. 고마워요 :) – Mirek
'E_NOINTERFACE'는 좋은 힌트입니다.당신은 어떤 물건을 가지고 있으며 그것은 당신의 주문 클래스임을 압니다. 하지만 필요한 인터페이스를 제공하지 않으므로 인터페이스 가시성과 관련된 문제 일뿐입니다. –