2009-03-27 5 views
1

내가 인터페이스에 대한 방법은는 SAFEARRAY는 Interop를

STDMETHODIMP CWrapper::RUN(long iDataSize, SAFEARRAY** iData) 

내가 가져

[id(1), helpstring("method RUN")] HRESULT RUN([in] long nSize, [in, size_is(nSize)] SAFEARRAY(_MyDataType*)* iData); 

처럼이 기능에 대한 MIDL이 보이는 ATL의 COM 서버를 가지고 작업을 가져올 수 없습니다 이 프로젝트에서 tlb를 사용하여 tlbimp를 사용하므로 원시 배열을 사용할 수 있습니다. 입력이 이미 할당 내 C# 프로그램 내부에서 다른 COM 개체로 가득

m_ServerWrapper.RUN(iInputs.Length,ref iInputs) 

을 다음과 같이 나는 다음의 C#에서 호출. 자, 내가 C++ 래퍼를 호출하면, 이 내 safearray에 있고, CWrapper::RUN의 후속 COM 객체에 대한 호출은 배열로 실패하여 최종 dll을 만들지 못합니다. 그것은 할당되지 않은 것으로 나타납니다. 누군가 내가 뭘 잘못하고 있는지 어떤 단서가 있습니까? 감사합니다

편집 : 내가 그 배열은 C#에서 잘 보인다 명시해야합니다.

EDIT2 : iData safearray가 IDispatch* = 0x0000000 <Bad Ptr>, 5, 0x0000000 <Bad Ptr>({lpvtbl = 0xblahblah},... 인 디버거가 표시됩니다. 내 정보가 도착하는 것처럼 보입니다.

+0

_MyDataType도 IDL에 정의되어 있습니까? 그렇지 않다면 거기에서해야합니다. 또 다른 이유 : 왜 nSize가 필요합니까? SAFEARRAY는 자체 크기를 유지합니다. –

답변

0

일반적인 C# 배열은 SAFEARRAY와 다릅니다. 나는 당신이 당신의 자신의 할 생각 :

[StructLayout(LayoutKind.Sequential)] 
struct SafeArray 
{ 
    public ushort dimensions; 
    public ushort features;  
    public uint  elementSize; 
    public uint  locks;  
    public IntPtr dataPtr;  
    public uint  elementCount; 
    public int  lowerBound; 
} 

그런 다음 메모리를 만들 수 Marshal.AllocCoTaskMem()를 사용합니다. 모든 데이터를 채운 다음 전달하십시오.

+1

찾을 수있는 모든 문서는 interop 계층이 배열을 safearray로 마샬링해야 함을 나타냅니다. – Steve