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

비밀번호

댓글 작성자
 




... 136  137  138  139  140  141  142  143  144  145  146  147  148  [149]  150  ...
NoWriterDateCnt.TitleFile(s)
1328정성태8/20/201233242개발 환경 구성: 163. IIS 7 - "MIME Types" 설정 아이콘이 없는 경우
1327정성태8/19/201237985Windows: 58. Windows 8 정식 버전을 설치해 보고... [14]
1326정성태8/19/201224302오류 유형: 160. Visual Studio 2010 Team Explorer 설치 오류
1325정성태8/15/201224332개발 환경 구성: 162. 닷넷 개발자가 컴파일해 본 리눅스
1324정성태8/15/201226358.NET Framework: 332. 함수형 언어의 코드가 그렇게 빠를까? [4]파일 다운로드1
1323정성태8/4/201228134.NET Framework: 331. C# - 클래스 안에 구조체를 포함하는 경우 발생하는 dynamic 키워드의 부작용 [2]
1322정성태8/3/201227760개발 환경 구성: 161. Ubuntu 리눅스의 Hyper-V 지원 (마우스, 네트워크)
1321정성태7/31/201227044개발 환경 구성: 160. Azure - Virtual Machine의 VHD 파일 다운로드 [2]
1320정성태7/30/201229031Math: 10. C# - (타)원 영역의 마우스 클릭 판단파일 다운로드1
1319정성태7/26/201227586개발 환경 구성: 159. Azure - 네트워크 포트 여는 방법 [1]
1317정성태7/24/201226450오류 유형: 159. SpeechRecognitionEngine.SetInputToDefaultAudioDevice 호출 시 System.InvalidOperationException 예외 발생
1316정성태7/18/201284559개발 환경 구성: 158. .NET 응용 프로그램에서 Oracle XE 11g 사용
1315정성태7/17/201229342개발 환경 구성: 157. Azure - Virtual Machine 구성 [2]
1314정성태7/16/201224372개발 환경 구성: 156. Azure - 2개 이상의 서비스 계정을 가지고 있을 때 프로젝트를 배포하는 방법
1313정성태7/16/201236521오류 유형: 158. Hyper-V 설치 후 VM 시작이 안되는 경우
1312정성태7/15/201236381Math: 9. 황금비율 증명
1311정성태7/15/201229058Math: 8. C# - 피보나치 수열의 사각형과 황금 나선(Golden spiral) 그리기파일 다운로드1
1310정성태7/13/201232482Math: 7. C# - 펜타그램(Pentagram) 그리기파일 다운로드1
1309정성태7/13/201230562개발 환경 구성: 155. 윈도우 운영체제에서 기본적으로 사용할 수 있는 압축 해제 방법
1308정성태7/3/201225969.NET Framework: 330. IEnumerator는 언제나 읽기 전용일까?파일 다운로드1
1307정성태6/30/201228230개발 환경 구성: 154. Sysnet, Azure를 만나다. [5]
1306정성태6/29/201228813제니퍼 .NET: 22. 눈으로 확인하는 connectionManagement의 maxconnection 설정값 [4]
1305정성태6/28/201226982오류 유형: 157. IIS 6 - WCF svc 호출 시 404 Not Found 발생
1304정성태6/27/201227798개발 환경 구성: 153. sysnet 첨부 파일을 Azure Storage에 마이그레이션 [3]파일 다운로드1
1303정성태6/26/201227278개발 환경 구성: 152. sysnet DB를 SQL Azure 데이터베이스로 마이그레이션
1302정성태6/25/201229304개발 환경 구성: 151. Azure 웹 사이트에 사용자 도메인 네임 연결하는 방법
... 136  137  138  139  140  141  142  143  144  145  146  147  148  [149]  150  ...