您好,我从 https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/set-se-translator?view=msvc-170 得到了这个示例
// 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();
}
我尝试在我的 Windows 10 x64 pro 笔记本电脑上使用 mingw-w64 进行编译(安装 msys2)。
g++ gnu_better_seh.cc
海湾合作委员会详细信息:
c:\work>gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=C:/winoss/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-14.2.0/configure --prefix=/ucrt64 --with-local-prefix=/ucrt64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/ucrt64/include --libexecdir=/ucrt64/lib --enable-bootstrap --enable-checking=release --with-arch=nocona --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++,rust,jit --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts --enable-libstdcxx-time --disable-libstdcxx-pch --enable-lto --enable-libgomp --disable-libssp --disable-multilib --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/ucrt64 --with-mpfr=/ucrt64 --with-mpc=/ucrt64 --with-isl=/ucrt64 --with-pkgversion='Rev1, Built by MSYS2 project' --with-bugurl=https://github.com/msys2/MINGW-packages/issues --with-gnu-as --with-gnu-ld --disable-libstdcxx-debug --enable-plugin --with-boot-ldflags=-static-libstdc++ --with-stage1-ldflags=-static-libstdc++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.2.0 (Rev1, Built by MSYS2 project)
但我明白了
c:\work>g++ gnu_better_seh.cc
C:/winoss/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\VASILI~1\AppData\Local\Temp\ccprbtUh.o:gnu_better_seh:(.text$_ZN20Scoped_SE_TranslatorC1EPFvjP19_EXCEPTION_POINTERSE[_ZN20Scoped_SE_TranslatorC1EPFvjP19_EXCEPTION_POINTERSE]+0x1a): undefined reference to `__imp__Z18_set_se_translatorPFvjP19_EXCEPTION_POINTERSE'
C:/winoss/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\VASILI~1\AppData\Local\Temp\ccprbtUh.o:gnu_better_seh:(.text$_ZN20Scoped_SE_TranslatorD1Ev[_ZN20Scoped_SE_TranslatorD1Ev]+0x19): undefined reference to `__imp__Z18_set_se_translatorPFvjP19_EXCEPTION_POINTERSE'
collect2.exe: error: ld returned 1 exit status
问题是什么?怎么修改?
当使用
_set_se_translator
定义
extern "C"
时构建
这就是我所做的:
编辑
mingw64/x86_64-w64-mingw32/include/eh.h
更改线路
_CRTIMP _se_translator_function __cdecl _set_se_translator(_se_translator_function _NewPtFunc);
至:
extern "C" _CRTIMP _se_translator_function __cdecl _set_se_translator(_se_translator_function _NewPtFunc);
然后我用
构建g++ gnu_better_seh.cc -lvcruntime140_app
或
g++ gnu_better_seh.cc -lucrtbase