bestsource

C# IT 유형 정보.VBA 클래스의 라이브 인스턴스를 전달할 때 GetContainingTypeLib가 실패함

bestsource 2023. 8. 17. 21:34
반응형

C# IT 유형 정보.VBA 클래스의 라이브 인스턴스를 전달할 때 GetContainingTypeLib가 실패함

그래서 나는 전화하는 것을 실험했습니다.ITypeInfoVBA 클래스 인스턴스에서 그리고 유망해 보이지만, 유형 라이브러리와 유사한 포함 프로젝트에 대한 참조를 얻을 수 있는지 확인하고 싶었습니다.내 생각에는 말이지…ITypeInfo.GetContainingTypeLib유용할 수 있지만 VBA가 작동하지 않는다는 예외가 발생합니다.VBA가 표준 COM 사양과 어떻게 다른 방식으로 작업을 수행할 수 있는지에 대해 아는 사람이 있습니까?

C# 클래스 라이브러리 코드는 여기에 있습니다.COM interop 및 set에 등록COMVisible(true)VBA에서 액세스할 수 있도록 AssemblyInfo.cs 에 있습니다.아래에 제공된 VBA 클라이언트 코드입니다.

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;


namespace TypeLibraryInspector
{
    [ComImport()]
    [Guid("00020400-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IDispatch
    {
        [PreserveSig]
        int GetTypeInfoCount(out int Count);

        [PreserveSig]
        int GetTypeInfo
            (
                [MarshalAs(UnmanagedType.U4)] int iTInfo,
                [MarshalAs(UnmanagedType.U4)] int lcid,
                out System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo
            );


        //void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler,
        //        MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo);

        //void GetTypeInfo(int typeInfoIndex, int lcid,  out IntPtr piTypeInfo);


        [PreserveSig]
        int GetIDsOfNames
            (
                ref Guid riid,
                [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)]
                string[] rgsNames,
                int cNames,
                int lcid,
                [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId
            );

        [PreserveSig]
        int Invoke
            (
                int dispIdMember,
                ref Guid riid,
                uint lcid,
                ushort wFlags,
                ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams,
                out object pVarResult,
                ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo,
                IntPtr[] pArgErr
            );
    }


    public interface IInspector
    {
        void InspectThisObject(object vbaClassInstance);
    }

    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IInspector))]

    public class Inspector : IInspector
    {
        private const int S_OK = 0; //From WinError.h
        private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800



        void IInspector.InspectThisObject(object vbaClassInstance)
        {
            //https://limbioliong.wordpress.com/2011/10/18/obtain-type-information-of-idispatch-based-com-objects-from-managed-code/
            IDispatch pDispatch = (IDispatch)vbaClassInstance;

            ITypeInfo piTypeInfo;
            pDispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out piTypeInfo);

            string s1; string s2; string s3;
            int i1;
            piTypeInfo.GetDocumentation(-1, out s1, out s2, out i1, out s3);
            //s1 = "Class1" good
            //s2 = null     shame

            ITypeLib piTypeLib;
            int pIndex;

            piTypeInfo.GetContainingTypeLib(out piTypeLib, out pIndex); // <-- throws Exception 0x800A88C1

        }
    }
}

어떤 클라이언트 VBA가 여기에 있습니다.

Sub Test()

    Dim oInspector As TypeLibraryInspector.Inspector
    Set oInspector = New TypeLibraryInspector.Inspector

    Dim oClass1 As Class1
    Set oClass1 = New Class1

    oInspector.InspectThisObject oClass1

End Sub

클래스 1이 어떤 클래스든 될 수 있는 곳에서, 저는 두 개의 빈 기능을 가지고 있지만 그것은 관련이 없다고 생각합니다.

저는 동등한 C++ 질문을 했습니다.

dll이 노출된 경우 regsvr32에 등록해야 합니다.

또한 .net 어셈블리를 GAC해야 할 수도 있습니다.

언급URL : https://stackoverflow.com/questions/51912746/c-sharp-itypeinfo-getcontainingtypelib-fails-when-passed-live-instance-of-vba-cl

반응형