Microsoft MVP성태의 닷넷 이야기
.NET Framework: 1072. C# - CoCreateInstance 관련 Inteop 오류 정리 [링크 복사], [링크+제목 복사],
조회: 15379
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 11개 있습니다.)

C# - CoCreateInstance 관련 Inteop 오류 정리

CoCreateInstance의 pinvoke 호출을 다음과 같이 정의해 볼까요?

[DllImport("ole32.dll")]
internal static extern int CoCreateInstance(
    [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
    [MarshalAs(UnmanagedType.IUnknown)] IntPtr pUnkOuter,
    CLSCTX dwClsCtx,
    [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
    [In, Out] ref IntPtr ppv);

이걸로 사용해 보면,

using System;
using System.Runtime.InteropServices;

class Program
{
    [Flags]
    internal enum CLSCTX : uint
    {
        INPROC_SERVER = 0x1,
        INPROC_HANDLER = 0x2,
        LOCAL_SERVER = 0x4,
        INPROC_SERVER16 = 0x8,
        REMOTE_SERVER = 0x10,
        INPROC_HANDLER16 = 0x20,
        RESERVED1 = 0x40,
        RESERVED2 = 0x80,
        RESERVED3 = 0x100,
        RESERVED4 = 0x200,
        NO_CODE_DOWNLOAD = 0x400,
        RESERVED5 = 0x800,
        NO_CUSTOM_MARSHAL = 0x1000,
        ENABLE_CODE_DOWNLOAD = 0x2000,
        NO_FAILURE_LOG = 0x4000,
        DISABLE_AAA = 0x8000,
        ENABLE_AAA = 0x10000,
        FROM_DEFAULT_CONTEXT = 0x20000,
        ACTIVATE_32_BIT_SERVER = 0x40000,
        ACTIVATE_64_BIT_SERVER = 0x80000,
        INPROC = INPROC_SERVER | INPROC_HANDLER,
        SERVER = INPROC_SERVER | LOCAL_SERVER | REMOTE_SERVER,
        ALL = SERVER | INPROC_HANDLER
    }

    [DllImport("ole32.dll")]
    internal static extern int CoCreateInstance(
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
        [MarshalAs(UnmanagedType.IUnknown)] IntPtr /* nuint */ pUnkOuter,
        CLSCTX dwClsCtx,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        [In, Out] ref IntPtr ppv);

    public static Guid CLSID_FolderInitHandler = new Guid("469afbdf-084f-4dc9-904f-9e824c48bc37");
    public static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");

    static void Main(string[] args)
    {
        IntPtr pUnknown = IntPtr.Zero;

        try
        {
            int hr = CoCreateInstance(CLSID_FolderInitHandler, IntPtr.Zero /* 0 */, CLSCTX.INPROC_SERVER, IID_IUnknown, ref pUnknown);
            Console.WriteLine(hr);
        }
        finally
        {
            if (pUnknown != IntPtr.Zero)
            {
                Marshal.Release(pUnknown);
            }
        }
    }
}

실행 시 다음과 같은 예외가 발생합니다.

Unhandled Exception: System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #2': Invalid managed/unmanaged type combination (Int/UInt must be paired with SysInt or SysUInt).
   at Program.CoCreateInstance(Guid rclsid, IntPtr pUnkOuter, CLSCTX dwClsCtx, Guid riid, IntPtr& ppv)
   at Program.Main(String[] args)

왜냐하면, UnmanagedType.IUnknown으로 마샬링을 지정했으면 IntPtr로 하면 안 되고 object로 해야 합니다.

[DllImport("ole32.dll")]
internal static extern int CoCreateInstance([In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
    [MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
    CLSCTX dwClsCtx, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [In, Out] ref IntPtr ppv);

int hr = CoCreateInstance(CLSID_FolderInitHandler, null, CLSCTX.INPROC_SERVER, IID_IUnknown, ref pUnknown);
Console.WriteLine(hr); // 출력 결과 0

혹은 IntPtr로 할 거라면 MarshalAs를 지정하지 말아야 합니다.

[DllImport("ole32.dll")]
internal static extern int CoCreateInstance([In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
    IntPtr pUnkOuter,
    CLSCTX dwClsCtx, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [In, Out] ref IntPtr ppv);

int hr = CoCreateInstance(CLSID_FolderInitHandler, IntPtr.Zero, CLSCTX.INPROC_SERVER, IID_IUnknown, ref pUnknown);
Console.WriteLine(hr); // 출력 결과 0

또 하나 실수할 수 있는 것은 MarshalAs를 지정한 object를,

[DllImport("ole32.dll")]
internal static extern int CoCreateInstance([In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
    [MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
    CLSCTX dwClsCtx, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [In, Out] ref IntPtr ppv);

IntPtr.Zero로 던졌을 때입니다.

int hr = CoCreateInstance(CLSID_FolderInitHandler, IntPtr.Zero, CLSCTX.INPROC_SERVER, IID_IUnknown, ref pUnknown);
Console.WriteLine(hr); // 출력 결과: -2147221232

이번에는 예외가 발생하지는 않고 hr로 반환합니다. 그래도 hr 값의 의미를 보면 pUnkOuter 인자에서 잘못된 것임을 짐작게 합니다.

0x80040110 Class does not support aggregation (or class object is remote) 

(첨부 파일은 이 글의 예제 코드를 포함합니다.)




C# - CoCreateInstance 관련 Inteop 오류 정리
; https://www.sysnet.pe.kr/2/0/12678

Wslhub.Sdk 사용으로 알아보는 CoInitializeSecurity 사용 제약
; https://www.sysnet.pe.kr/2/0/12665

별도 DLL에 포함된 타입을 STAThread Main 메서드에서 사용하는 경우 CoInitializeSecurity 자동 호출
; https://www.sysnet.pe.kr/2/0/12666

COM+ 서버 응용 프로그램을 이용해 CoInitializeSecurity 제약 해결
; https://www.sysnet.pe.kr/2/0/12667

ionescu007/lxss github repo에 공개된 lxssmanager.dll의 CLSID_LxssUserSession/IID_ILxssSession 사용법
; https://www.sysnet.pe.kr/2/0/12676

역공학을 통한 lxssmanager.dll의 ILxssSession 사용법 분석
; https://www.sysnet.pe.kr/2/0/12677

C# - DLL Surrogate를 이용한 Out-of-process COM 개체 제작
; https://www.sysnet.pe.kr/2/0/12668

DLL Surrogate를 이용한 Out-of-process COM 개체에서의 CoInitializeSecurity 문제
; https://www.sysnet.pe.kr/2/0/12670

CoInitializeSecurity의 전역 설정을 재정의하는 CoSetProxyBlanket 함수 사용법
; https://www.sysnet.pe.kr/2/0/12679




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 2/4/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... [166]  167  168  169  170  171  172  173  174  175  176  177  178  179  180  ...
NoWriterDateCnt.TitleFile(s)
893정성태7/25/201027366오류 유형: 99. .NET 4.0 설치된 윈도우 7에서 SQL Server 2008 R2 설치 오류
892정성태7/9/201029090오류 유형: 98. 영문 윈도우에 한글 SQL Server 2008 R2 설치할 때 오류 [4]
891정성태7/8/201024971오류 유형: 97. MsiGetProductInfo failed to retrieve ProductVersion for package with Product Code = '{...}'. Error code: 1605. [2]
889정성태7/5/201026651.NET Framework: 179. Dictionary.Get(A) 대신 Dictionary.Get(A.GetHashCode())를 사용해서는 안 되는 이유 [1]
888정성태6/30/201024455오류 유형: 96. Hyper-V 연결 오류 - A connection will not be made because credentials may not be sent to the remote computer
887정성태6/23/201034290개발 환경 구성: 79. Hyper-V의 가상 머신에서 소리 재생 방법 [2]
886정성태6/23/201022471제니퍼 .NET: 14. ASMX, WCF 호출 모니터링 및 누수 확인
885정성태6/20/201024037개발 환경 구성: 78. COM+ 서버에서 COM+ 서버를 호출하는 방법
884정성태6/20/201026977제니퍼 .NET: 13. COM+ 서버 모니터링 [2]
883정성태6/18/201028897개발 환경 구성: 77. Appinit_Dlls로 구현한 환경 변수 설정 DLL [5]파일 다운로드1
882정성태6/17/201031684개발 환경 구성: 76. JKS(Java Key Store)에 저장된 인증서를 ActiveX 코드 서명에 사용하는 방법 [1]
881정성태6/14/201021114제니퍼 .NET: 12. COM+ 호출 모니터링 및 누수 확인
879정성태6/10/201023776제니퍼 .NET: 11. 소켓 모니터링 기능으로 본 ASP.NET의 소켓 풀링 기능 [1]
878정성태6/6/201023575제니퍼 .NET: 10. 소켓 모니터링 기능으로 본 WCF의 WSDualHttpBinding 성능 부하
877정성태5/31/201020291제니퍼 .NET: 9. 성능 관리 퀴즈 세 번째 문제 (닷넷 개발자 컨퍼런스)
876정성태5/31/201019733제니퍼 .NET: 8. 성능 관리 퀴즈 두 번째 문제 (닷넷 개발자 컨퍼런스) [2]
875정성태5/30/201021491제니퍼 .NET: 7. 성능 관리 퀴즈 첫 번째 문제 (닷넷 개발자 컨퍼런스)
873정성태5/19/201028341제니퍼 .NET: 6. 제니퍼를 위한 방화벽 설정
872정성태5/15/201027673제니퍼 .NET: 5. 제니퍼 서버 - NT 서비스로 구동시키는 방법
871정성태5/13/201034242VC++: 40. MSBuild를 이용한 VC++ 프로젝트 빌드파일 다운로드1
870정성태5/12/201025273제니퍼 .NET: 4. 닷넷 APM 솔루션 - 제니퍼 닷넷의 기능 요약 [2]
869정성태11/8/201926714오류 유형 : 95. WCF 인증서 설정 관련 오류 정리 [4]
865정성태5/5/201029012개발 환경 구성: 75. 인증서의 개인키를 담은 물리 파일 위치 알아내는 방법파일 다운로드1
864정성태5/4/201032851.NET Framework: 178. WCF - 사용자 정의 인증 구현 예제 [4]파일 다운로드1
863정성태5/4/201058781개발 환경 구성: 74. 인증서 관련(CER, PVK, SPC, PFX) 파일 만드는 방법 [1]파일 다운로드1
862정성태5/3/201020667제니퍼 .NET: 3. 제2회 닷넷 개발자 컨퍼런스에서 뵙겠습니다. ^^
... [166]  167  168  169  170  171  172  173  174  175  176  177  178  179  180  ...