CoDisconnectContext
関数シグネチャ
// OLE32.dll
#include <windows.h>
HRESULT CoDisconnectContext(
DWORD dwTimeout
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| dwTimeout | DWORD | in | すべてのオブジェクトのプロキシ接続が切断されていない場合でも、この時間(ミリ秒単位)が経過すると CoDisconnectContext が戻ります。このパラメーターには INFINITE を指定することもできます。 |
戻り値の型: HRESULT
公式ドキュメント
現在のコンテキスト内のオブジェクトを指すすべてのインターフェイスポインターのために維持されている、すべてのプロキシ接続を切断します。
戻り値
この関数は、標準の戻り値 E_FAIL、E_INVALIDARG、E_OUTOFMEMORY のほか、次の値を返すことがあります。
| 戻り値 | 説明 |
|---|---|
| すべてのオブジェクトのプロキシ接続が正常に切断されました。 | |
| dwTimeout で指定された時間内に、すべてのプロキシ接続を削除できませんでした。 | |
|
現在のコンテキストは切断できません。 |
| オブジェクトが、自身が存在するコンテキストに対して CoDisconnectContext を呼び出そうとしました。dwTimeout が INFINITE に設定されている場合、これにより関数がタイムアウトしてデッドロックに陥ります。 |
解説(Remarks)
CoDisconnectContext 関数は、共有サービスホストでサービスのアンロードをサポートするために使用されます。共有サービスホストでは、同じプロセス内で実行されている他の COM サーバーに影響を与えずに、サービスのバイナリをアンロードする必要があります。プロセスの有効期間を制御していて、プロセスが終了するまでアンロードを行わない場合は、COM インフラストラクチャが必要なクリーンアップを自動的に実行するため、この関数を呼び出す必要はありません。
CoDisconnectContext 関数を使用すると、サーバーは現在のコンテキスト内のすべてのオブジェクトについて、すべての外部クライアントを正しく切断できます。既定のコンテキストは切断できません。CoDisconnectContext を使用するには、まず切断可能なコンテキストを作成し、切断対象のオブジェクトのクラスファクトリをそのコンテキスト内で登録する必要があります。これは IContextCallback インターフェイスを使用して行えます。
CoDisconnectContext が RPC_E_TIMEOUT を返した場合、これは関数がオブジェクトを切断しなかったことを示すのではなく、オブジェクトに対する未完了の呼び出しのために、dwTimeout で指定された時間内にすべての切断を完了できなかったことを示します。すべてのオブジェクトは、それらに対するすべての呼び出しが完了した後に切断されます。
CoDisconnectContext が S_OK を返すまで、サービスをホストする DLL をアンロードすることは安全ではありません。関数が RPC_E_TIMEOUT を返した場合、サービスは他のクリーンアップを実行してかまいません。サービスは、関数が S_OK を返すまで呼び出しを繰り返す必要があり、その後で安全に DLL をアンロードできます。
CoDisconnectContext 関数は、次のタスクを実行します。
- 現在のコンテキスト内のすべてのオブジェクトに対して CoDisconnectObject を呼び出します。
- すべてのオブジェクトが切断されるか、タイムアウトが経過するまでブロックします。
- 非同期 COM 呼び出しはサポートされていません。
- インプロセスオブジェクトは、CLSCTX_LOCAL_SERVER フラグを使用して登録および有効化する必要があります。そうしないと切断されません。
- COM+ はサポートされていません。
- COM インターフェイスポインターはコンテキスト依存です。したがって、切断対象のコンテキスト内で作成されたインターフェイスポインターは、そのコンテキスト内でのみ使用できます。
例
IContextCallback *icc;
hr = CoCreateInstance(CLSID_ContextSwitcher, NULL, CLSCTX_INPROC_SERVER, IID_IContextCallback, (void**)&icc);
icc->ContextCallback(EnterCallback, NULL, IID_IContextCallback, 5, NULL);
HRESULT __stdcall EnterCallback(ComCallData *pv)
{
return CoRegisterClassObject(...);
}
/* All objects created by the class factories registered in the callback will be put into the newly created context.
To disconnect, re-enter the context, revoke the class factories, and call CoDisconnectContext. */
icc->ContextCallback(DisconnectCallback, NULL, IID_IContextCallback, 5, NULL);
HRESULT __stdcall DisconnectCallback(ComCallData *pv)
{
CoRevokeClassObject(...);
return CoDisconnectContext(timeout);
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// OLE32.dll
#include <windows.h>
HRESULT CoDisconnectContext(
DWORD dwTimeout
);[DllImport("OLE32.dll", ExactSpelling = true)]
static extern int CoDisconnectContext(
uint dwTimeout // DWORD
);<DllImport("OLE32.dll", ExactSpelling:=True)>
Public Shared Function CoDisconnectContext(
dwTimeout As UInteger ' DWORD
) As Integer
End Function' dwTimeout : DWORD
Declare PtrSafe Function CoDisconnectContext Lib "ole32" ( _
ByVal dwTimeout As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
CoDisconnectContext = ctypes.windll.ole32.CoDisconnectContext
CoDisconnectContext.restype = ctypes.c_int
CoDisconnectContext.argtypes = [
wintypes.DWORD, # dwTimeout : DWORD
]require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('OLE32.dll')
CoDisconnectContext = Fiddle::Function.new(
lib['CoDisconnectContext'],
[
-Fiddle::TYPE_INT, # dwTimeout : DWORD
],
Fiddle::TYPE_INT)#[link(name = "ole32")]
extern "system" {
fn CoDisconnectContext(
dwTimeout: u32 // DWORD
) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("OLE32.dll")]
public static extern int CoDisconnectContext(uint dwTimeout);
"@
$api = Add-Type -MemberDefinition $sig -Name 'OLE32_CoDisconnectContext' -Namespace Win32 -PassThru
# $api::CoDisconnectContext(dwTimeout)#uselib "OLE32.dll"
#func global CoDisconnectContext "CoDisconnectContext" sptr
; CoDisconnectContext dwTimeout ; 戻り値は stat
; dwTimeout : DWORD -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "OLE32.dll"
#cfunc global CoDisconnectContext "CoDisconnectContext" int
; res = CoDisconnectContext(dwTimeout)
; dwTimeout : DWORD -> "int"; HRESULT CoDisconnectContext(DWORD dwTimeout)
#uselib "OLE32.dll"
#cfunc global CoDisconnectContext "CoDisconnectContext" int
; res = CoDisconnectContext(dwTimeout)
; dwTimeout : DWORD -> "int"import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ole32 = windows.NewLazySystemDLL("OLE32.dll")
procCoDisconnectContext = ole32.NewProc("CoDisconnectContext")
)
// dwTimeout (DWORD)
r1, _, err := procCoDisconnectContext.Call(
uintptr(dwTimeout),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // HRESULTfunction CoDisconnectContext(
dwTimeout: DWORD // DWORD
): Integer; stdcall;
external 'OLE32.dll' name 'CoDisconnectContext';result := DllCall("OLE32\CoDisconnectContext"
, "UInt", dwTimeout ; DWORD
, "Int") ; return: HRESULT●CoDisconnectContext(dwTimeout) = DLL("OLE32.dll", "int CoDisconnectContext(dword)")
# 呼び出し: CoDisconnectContext(dwTimeout)
# dwTimeout : DWORD -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "ole32" fn CoDisconnectContext(
dwTimeout: u32 // DWORD
) callconv(std.os.windows.WINAPI) i32;proc CoDisconnectContext(
dwTimeout: uint32 # DWORD
): int32 {.importc: "CoDisconnectContext", stdcall, dynlib: "OLE32.dll".}pragma(lib, "ole32");
extern(Windows)
int CoDisconnectContext(
uint dwTimeout // DWORD
);ccall((:CoDisconnectContext, "OLE32.dll"), stdcall, Int32,
(UInt32,),
dwTimeout)
# dwTimeout : DWORD -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t CoDisconnectContext(
uint32_t dwTimeout);
]]
local ole32 = ffi.load("ole32")
-- ole32.CoDisconnectContext(dwTimeout)
-- dwTimeout : DWORD
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('OLE32.dll');
const CoDisconnectContext = lib.func('__stdcall', 'CoDisconnectContext', 'int32_t', ['uint32_t']);
// CoDisconnectContext(dwTimeout)
// dwTimeout : DWORD -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("OLE32.dll", {
CoDisconnectContext: { parameters: ["u32"], result: "i32" },
});
// lib.symbols.CoDisconnectContext(dwTimeout)
// dwTimeout : DWORD -> "u32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t CoDisconnectContext(
uint32_t dwTimeout);
C, "OLE32.dll");
// $ffi->CoDisconnectContext(dwTimeout);
// dwTimeout : DWORD
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
public interface Ole32 extends StdCallLibrary {
Ole32 INSTANCE = Native.load("ole32", Ole32.class);
int CoDisconnectContext(
int dwTimeout // DWORD
);
}@[Link("ole32")]
lib LibOLE32
fun CoDisconnectContext = CoDisconnectContext(
dwTimeout : UInt32 # DWORD
) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef CoDisconnectContextNative = Int32 Function(Uint32);
typedef CoDisconnectContextDart = int Function(int);
final CoDisconnectContext = DynamicLibrary.open('OLE32.dll')
.lookupFunction<CoDisconnectContextNative, CoDisconnectContextDart>('CoDisconnectContext');
// dwTimeout : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function CoDisconnectContext(
dwTimeout: DWORD // DWORD
): Integer; stdcall;
external 'OLE32.dll' name 'CoDisconnectContext';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "CoDisconnectContext"
c_CoDisconnectContext :: Word32 -> IO Int32
-- dwTimeout : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let codisconnectcontext =
foreign "CoDisconnectContext"
(uint32_t @-> returning int32_t)
(* dwTimeout : DWORD -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library ole32 (t "OLE32.dll"))
(cffi:use-foreign-library ole32)
(cffi:defcfun ("CoDisconnectContext" co-disconnect-context :convention :stdcall) :int32
(dw-timeout :uint32)) ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $CoDisconnectContext = Win32::API::More->new('OLE32',
'int CoDisconnectContext(DWORD dwTimeout)');
# my $ret = $CoDisconnectContext->Call($dwTimeout);
# dwTimeout : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f CoDisconnectObject — オブジェクトへの全リモートプロキシ接続を切断する。
- i IContextCallback