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

비밀번호

댓글 작성자
 




... [91]  92  93  94  95  96  97  98  99  100  101  102  103  104  105  ...
NoWriterDateCnt.TitleFile(s)
11655정성태8/16/201817893사물인터넷: 28. 저항과 병렬로 연결한 LED파일 다운로드1
11654정성태8/15/201819170사물인터넷: 27. 병렬 회로의 저항, 전압 및 전류파일 다운로드1
11653정성태8/14/201820007사물인터넷: 26. 입력 전압에 따른 LED의 전압/저항 변화 [1]파일 다운로드1
11652정성태8/14/201817455사물인터넷: 25. 컬렉터 9V, 베이스에 5V와 3.3V 전압으로 테스트하는 C1815 트랜지스터파일 다운로드1
11651정성태8/14/201822563사물인터넷: 24. 9V 전압에서 테스트하는 C1815 트랜지스터 [1]파일 다운로드3
11650정성태8/14/201816971사물인터넷: 23. 가변저항으로 분압파일 다운로드1
11649정성태8/12/201819299사물인터넷: 22. 저항에 따른 전류 테스트파일 다운로드1
11648정성태8/12/201820729사물인터넷: 21. 퓨즈를 이용한 회로 보호파일 다운로드3
11647정성태8/8/201820852오류 유형: 476. 음수의 음수는 여전히 음수가 되는 수(절대값이 음수인 수)
11646정성태8/8/201816882오류 유형: 475. gacutil.exe 실행 시 "Failure initializing gacutil" 오류 발생
11645정성태8/8/201819088오류 유형: 474. 닷넷 COM+ - Failed to load the runtime. [1]
11644정성태8/6/201821990디버깅 기술: 118. windbg - 닷넷 개발자를 위한 MEX Debugging Extension 소개
11643정성태8/6/201821616사물인터넷: 20. 아두이노 레오나르도 R3 호환 보드의 3.3v 핀의 LED 전압/전류 테스트 [1]파일 다운로드1
11642정성태8/3/201820428Graphics: 20. Unity - LightMode의 ForwardBase에 따른 _WorldSpaceLightPos0 값 변화
11641정성태8/3/201825952Graphics: 19. Unity로 실습하는 Shader (10) - 빌보드 구현 [1]파일 다운로드1
11640정성태8/3/201822113Graphics: 18. Unity - World matrix(unity_ObjectToWorld)로부터 Position, Rotation, Scale 값을 복원하는 방법파일 다운로드1
11639정성태8/2/201819684디버깅 기술: 117. windbg - 덤프 파일로부터 추출한 DLL을 참조하는 방법
11638정성태8/2/201818082오류 유형: 473. windbg - 덤프 파일로부터 추출한 DLL 참조 시 "Resolved file has a bad image, no metadata, or is otherwise inaccessible." 빌드 오류
11637정성태8/1/201822468Graphics: 17. Unity - World matrix(unity_ObjectToWorld)로부터 TRS(이동/회전/크기) 행렬로 복원하는 방법파일 다운로드1
11636정성태8/1/201829887Graphics: 16. 3D 공간에서 두 점이 이루는 각도 구하기파일 다운로드1
11635정성태8/1/201818594오류 유형: 472. C# 컴파일 오류 - Your project is not referencing the ".NETFramework,Version=v3.5" framework.
11634정성태8/1/201821528.NET Framework: 790. .NET Thread 상태가 Cooperative일 때 GC hang 현상 재현 방법파일 다운로드1
11633정성태7/29/201825488Graphics: 15. Unity - shader의 World matrix(unity_ObjectToWorld)를 수작업으로 구성 [2]파일 다운로드1
11632정성태7/28/201827786Graphics: 14. C# - Unity에서 캐릭터가 바라보는 방향을 기준으로 카메라의 위치 이동 및 회전하는 방법
11631정성태7/27/201829768Graphics: 13. Unity로 실습하는 Shader (9) - 투명 배경이 있는 텍스처 입히기 [1]
11630정성태7/27/201824959개발 환경 구성: 391. (GitHub 등과 직접 연동해) 소스 코드 디버깅을 쉽게 해 주는 SourceLink [3]
... [91]  92  93  94  95  96  97  98  99  100  101  102  103  104  105  ...