Microsoft MVP성태의 닷넷 이야기
.NET Framework: 1072. C# - CoCreateInstance 관련 Inteop 오류 정리 [링크 복사], [링크+제목 복사],
조회: 16081
글쓴 사람
정성태 (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

비밀번호

댓글 작성자
 




... [181]  182  183  184  185  186  187  188  189  190  191  192  193  194  195  ...
NoWriterDateCnt.TitleFile(s)
489정성태5/14/200722914.NET Framework: 87. .NET 2.0에서 C# 3.0 기능 사용하기
488정성태5/14/200721436Windows: 25. Multiple Input Queues
487정성태4/24/200727030VC++: 32. VC++에서 bool이 가지는 의미 [3]
486정성태3/22/200726059Windows: 24. DreamScene과 DWM(Desktop Window Manager)의 관계 [1]
485정성태3/17/200721423오류 유형: 32. VS.NET 2005 - x64 환경에서의 mixed 디버깅 환경 구성
484정성태3/17/200720521오류 유형: 31. SQL Compact Edition 설치 후 오류
483정성태3/17/200741959오류 유형: 30. x64 환경: .NET + COM 프로젝트 실행 시 오류 - 80040154 [2]
482정성태3/17/200731418Team Foundation Server: 17. 팀 프로젝트 접속 및 사용
481정성태3/17/200725377Team Foundation Server: 16. 팀 프로젝트 읽기 전용 사용자 등록
480정성태3/14/200723584.NET Framework: 86. GC(Garbage Collector)의 변화
479정성태3/14/200727527개발 환경 구성: 25. D820 - ReadyBoost 구동
478정성태3/14/200726955개발 환경 구성: 24. D820 고주파음 문제
477정성태3/14/200736235개발 환경 구성: 23. 비스타 x64 버전에서 서명되지 않은 드라이버 사용 [4]
476정성태3/9/200731673개발 환경 구성: 22. D820 노트북 - 설치 및 BitLocker 구성 [1]
475정성태3/6/200726051.NET Framework: 85. 공용 프로퍼티 자동 생성
474정성태3/5/200724275.NET Framework: 84. Lambda 표현식 응용 사례 [1]
473정성태3/4/200731345디버깅 기술: 14. TFS 오류 추적(TF53010, TF14105)
472정성태3/3/200730514디버깅 기술: 13. 예외 발생 시 Minidump 생성 - WinDBG [3]파일 다운로드1
471정성태3/1/200719617디버깅 기술: 12. Managed Method에 Break Point 걸기
469정성태2/28/200731228디버깅 기술: 11. (Managed) Main Method에 Break Point 걸기 [3]파일 다운로드1
470정성태3/1/200722635    답변글 디버깅 기술: 11.1. (Managed) Main Method에 Break Point 걸기 - 내용 보강
468정성태2/25/200732400COM 개체 관련: 20. 탭 브라우저의 윈도우 핸들 구하기 [3]
466정성태2/22/200724209Windows: 23. 롱혼 서버 코어 버전 [2]
465정성태2/21/200723171오류 유형: 29. TFS 관련 스케줄 작업 실패
464정성태2/25/200724318오류 유형: 28. TF10217, TF53010, TF14105 오류
463정성태2/21/200717139Team Foundation Server: 15. 포탈 사이트의 보고서 주소를 도메인 명으로 적용
... [181]  182  183  184  185  186  187  188  189  190  191  192  193  194  195  ...