_set_se_translator

Win32 özel durumlarını (C yapılandırılmış özel durumları) C++ türündeki özel durumlara çevirmek için iş parçacığı başına geri çağırma işlevi ayarlayın.

Sözdizimi

_se_translator_function _set_se_translator(
    _se_translator_function seTransFunction
);

Parametreler

seTransFunction
Yazdığınız C yapılandırılmış özel durum çevirisi işlevinin işaretçisi.

Dönüş değeri

önceki işlevin daha sonra geri yüklenebilmesi için tarafından _set_se_translatorkaydedilen önceki translator işlevinin işaretçisini döndürür. Önceki bir işlev ayarlanmamışsa, varsayılan davranışı geri yüklemek için dönüş değeri kullanılabilir; bu değer olabilir nullptr.

Açıklamalar

işlevi, _set_se_translator Win32 özel durumlarını (C yapılandırılmış özel durumları) C++ türündeki özel durumlar olarak işlemek için bir yol sağlar. Her bir C özel durumunun bir C++ catch işleyicisi tarafından işlenmesine izin vermek için, belirli bir sınıf türünü C özel durumuyla bağlamak için önce kullanılabilecek veya türetilebilen bir C özel durum sarmalayıcı sınıfı tanımlayın. Bu sınıfı kullanmak için, her C özel durumu oluşturulduğunda iç özel durum işleme mekanizması tarafından çağrılan özel bir C özel durum çevirisi işlevi yükleyin. Translator işlevinizin içinde, eşleşen bir C++ catch işleyicisi tarafından yakalanabilecek herhangi bir türemiş özel durum oluşturabilirsiniz.

kullanırken seçeneğini kullanmanız /EHa _set_se_translatorgerekir.

Özel bir çeviri işlevi belirtmek için, bağımsız değişkeni olarak çeviri işlevinizin adını kullanarak çağrısı _set_se_translator yapın. Yazdığınız translator işlevi, blokları olan try yığındaki her işlev çağrısı için bir kez çağrılır. Varsayılan translator işlevi yoktur.

Translator işleviniz, C++ türüne sahip özel durum oluşturmaktan başka bir şey yapmamalıdır. Oluşturma işlemine ek olarak herhangi bir işlem yaparsa (örneğin, bir günlük dosyasına yazma gibi) translator işlevinin çağrı sayısı platforma bağlı olduğundan programınız beklendiği gibi davranmayabilir.

Çok iş parçacıklı bir ortamda translator işlevleri her iş parçacığı için ayrı ayrı tutulur. Her yeni iş parçacığının kendi translator işlevini yüklemesi gerekir. Bu nedenle, her iş parçacığı kendi çeviri işleme sorumluluğundadır. _set_se_translator bir iş parçacığına özeldir; başka bir DLL farklı bir çeviri işlevi yükleyebilir.

seTransFunction Yazdığınız işlev yerel olarak derlenmiş bir işlev olmalıdır (ile /clrderlenmemelidir). Bağımsız değişken olarak işaretsiz bir tamsayı ve Win32 _EXCEPTION_POINTERS yapısının işaretçisini alması gerekir. Bağımsız değişkenler sırasıyla Win32 API'sine GetExceptionCode ve GetExceptionInformation işlevlerine yapılan çağrıların dönüş değerleridir.

typedef void (__cdecl *_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS* );

için _set_se_translator, CRT'ye dinamik olarak bağlanırken etkileri vardır; işlemdeki başka bir DLL işleyicinizi çağırabilir _set_se_translator ve işleyicinizi kendi dll'si ile değiştirebilir.

Yönetilen koddan (ile /clrderlenmiş kod) veya karışık yerel ve yönetilen koddan kullandığınızda_set_se_translator, çeviri aracı yalnızca yerel kodda oluşturulan özel durumları etkiler. Yönetilen kodda oluşturulan yönetilen özel durumlar (örneğin, oluşturulurken System::Exception) translator işlevi aracılığıyla yönlendirilmiyor. Win32 işlevi RaiseException kullanılarak yönetilen kodda ortaya çıkan veya sıfıra bölme özel durumu gibi bir sistem özel durumu nedeniyle oluşan özel durumlar çevirici aracılığıyla yönlendirilir.

Gereksinimler

Yordam Gerekli başlık
_set_se_translator <eh.h>

Daha fazla uyumluluk bilgisi için bkz . Uyumluluk.

Örnek: Catch __try özel durum hatası

Bu örnek, yapılandırılmış bir özel durum çeviricisi ayarlamak ve sınıfındaki Scoped_SE_Translatoreskisini RAII geri yüklemek için çağrıları sarmalar. Bu sınıf, kapsama özgü bir çeviriciyi tek bir bildirim olarak tanıtmanızı sağlar. Denetim kapsamdan ayrıldığında sınıf yıkıcısı özgün çeviriciyi geri yükler.

// crt_settrans.cpp
// compile with: cl /W4 /EHa crt_settrans.cpp
#include <stdio.h>
#include <windows.h>
#include <eh.h>
#include <exception>

class SE_Exception : public std::exception
{
private:
    const unsigned int nSE;
public:
    SE_Exception() noexcept : SE_Exception{ 0 } {}
    SE_Exception( unsigned int n ) noexcept : nSE{ n } {}
    unsigned int getSeNumber() const noexcept { return nSE; }
};

class Scoped_SE_Translator
{
private:
    const _se_translator_function old_SE_translator;
public:
    Scoped_SE_Translator( _se_translator_function new_SE_translator ) noexcept
        : old_SE_translator{ _set_se_translator( new_SE_translator ) } {}
    ~Scoped_SE_Translator() noexcept { _set_se_translator( old_SE_translator ); }
};

void SEFunc()
{
    __try
    {
        printf( "In __try, about to force exception\n" );
        int x = 5;
        int y = 0;
        int *p = &y;
        *p = x / *p;
    }
    __finally
    {
        printf( "In __finally\n" );
    }
}

void trans_func( unsigned int u, EXCEPTION_POINTERS* )
{
    throw SE_Exception( u );
}

int main()
{
    Scoped_SE_Translator scoped_se_translator{ trans_func };
    try
    {
        SEFunc();
    }
    catch( const SE_Exception& e )
    {
        printf( "Caught a __try exception, error %8.8x.\n", e.getSeNumber() );
    }
}
In __try, about to force exception
In __finally
Caught a __try exception, error c0000094.

Örnek: Catch SE_Exception hatası

tarafından _set_se_translator sağlanan işlevsellik yönetilen kodda kullanılamasa da, yerel kod kullanılarak #pragma unmanagedbelirtildiği sürece, bu yerel kod anahtarı altındaki /clr bir derlemede olsa bile yerel kodda bu eşlemeyi kullanabilirsiniz. Eşlenecek yönetilen kodda yapılandırılmış bir özel durum oluşturulduysa, özel durumu oluşturan ve işleyen kod işaretlenmelidir #pragma unmanaged. Aşağıdaki kodda olası bir kullanım gösterilmektedir. Daha fazla bilgi için bkz . Pragma yönergeleri ve __pragma ve _Pragma anahtar sözcükleri.

// crt_set_se_translator_clr.cpp
// compile with: cl /W4 /clr crt_set_se_translator_clr.cpp
#include <windows.h>
#include <eh.h>
#include <stdio.h>
#include <exception>

int thrower_func( int i ) {
   int y = 0;
   int *p = &y;
   *p = i / *p;
   return 0;
}

class SE_Exception : public std::exception
{
private:
    const unsigned int nSE;
public:
    SE_Exception() noexcept : SE_Exception{ 0 } {}
    SE_Exception( unsigned int n ) noexcept : nSE{ n } {}
    unsigned int getSeNumber() const noexcept { return nSE; }
};

class Scoped_SE_Translator
{
private:
    const _se_translator_function old_SE_translator;
public:
    Scoped_SE_Translator( _se_translator_function new_SE_translator ) noexcept
        : old_SE_translator{ _set_se_translator( new_SE_translator ) } {}
    ~Scoped_SE_Translator() noexcept { _set_se_translator( old_SE_translator ); }
};

#pragma unmanaged
void my_trans_func( unsigned int u, PEXCEPTION_POINTERS )
{
    throw SE_Exception( u );
}

void DoTest()
{
    try
    {
        thrower_func( 10 );
    }
    catch( const SE_Exception& e )
    {
        printf( "Caught SE_Exception, error %8.8x\n", e.getSeNumber() );
    }
    catch(...)
    {
        printf( "Caught unexpected SEH exception.\n" );
    }
}
#pragma managed

int main() {
    Scoped_SE_Translator scoped_se_translator{ my_trans_func };

    DoTest();
}
Caught SE_Exception, error c0000094

Ayrıca bkz.

Özel durum işleme yordamları
set_terminate
set_unexpected
terminate
unexpected