📄 makeloadtimetest.cpp
字号:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
//=============================================================
const unsigned nDLLs = 10;
const unsigned nExportedFunctions = 100;
const unsigned nGlobalVariablesPerFunction = 5;
//=============================================================
bool BeginMainFile( FILE ** pMainSource, FILE ** pMainHeader );
bool EndMainFile( FILE * pMainSource, FILE * pMainHeader );
bool BuildDLLFile(unsigned nFileNumber, FILE* pMainSource, FILE* pMainHeader);
//=============================================================
int main()
{
FILE * pMainSource;
FILE * pMainHeader;
if ( false == BeginMainFile( &pMainSource, &pMainHeader) )
return 1;
for ( unsigned i = 1; i <= nDLLs; i++ )
{
BuildDLLFile( i, pMainSource, pMainHeader );
}
EndMainFile( pMainSource, pMainHeader );
return 0;
}
bool BeginMainFile( FILE ** pMainSource, FILE ** pMainHeader )
{
FILE * pSource = fopen( "LoadTimeTest.CPP", "wt" );
FILE * pHeader = fopen( "LoadTimeTest.H", "wt" );
if ( !pSource || !pHeader )
return false;
fprintf( pSource, "#include \"LoadTimeTest.H\"\n" );
fprintf( pSource, "#include <windows.h>\n\n" );
fprintf( pSource, "int main(int argc)\n{\n" );
fprintf( pSource, " TerminateProcess( GetCurrentProcess(), 0 );\n" );
*pMainSource = pSource;
*pMainHeader = pHeader;
return true;
}
bool EndMainFile( FILE * pMainSource, FILE * pMainHeader )
{
fprintf( pMainSource, " return 0;\n" );
fprintf( pMainSource, "}\n" );
fclose( pMainSource );
fclose( pMainHeader );
return true;
}
bool BuildDLLFile( unsigned nFileNumber, FILE * pMainSource, FILE * pMainHeader )
{
char * pszBaseFileName = "LoadTimeTestDLL";
char szCPPName[MAX_PATH];
char szHeaderName[MAX_PATH];
sprintf( szCPPName, "%s%u.CPP", pszBaseFileName, nFileNumber );
sprintf( szHeaderName, "%s%u.H", pszBaseFileName, nFileNumber );
FILE * pFileCPP = fopen( szCPPName, "wt" );
if ( !pFileCPP )
return false;
FILE * pFileHeader = fopen( szHeaderName, "wt" );
if ( !pFileHeader )
return false;
fprintf( pMainHeader, "#include \"%s\"\n", szHeaderName );
fprintf( pFileCPP, "// Warning: Linker support for the #pragma comment(linker, \"/EXPORT:XXX\"\n" );
fprintf( pFileCPP, "// syntax may go away.\n" );
for ( unsigned i = 1; i <= nExportedFunctions; i++ )
{
char szBaseFunctionSig[512];
char szFunctionSig[512];
sprintf( szBaseFunctionSig, "LoadTimeDLL_%u_func_%u",
nFileNumber, i );
sprintf( szFunctionSig, "void %s(void)", szBaseFunctionSig );
//
// Make the global variable definitions
//
for ( unsigned j = 0; j < nGlobalVariablesPerFunction; j++ )
fprintf( pFileCPP, "void * g_var_n%u_%u;\n", i, j );
//
// make the #pragma that exports the function. Put inside a preprocessor
// #ifdef to enable "export by ordinal" or "export by name"
//
fprintf( pFileCPP, "#ifdef ORDINAL_EXPORTS\n" );
fprintf( pFileCPP, "#pragma comment( linker, \"/EXPORT:_%s,@%u,NONAME\")\n",
szBaseFunctionSig, i);
fprintf( pFileCPP, "#else\n" );
fprintf( pFileCPP, "#pragma comment( linker, \"/EXPORT:_%s\")\n",
szBaseFunctionSig, i);
fprintf( pFileCPP, "#endif\n" );
//
// Declare the first line of the function, and open '{'
//
fprintf( pFileCPP, "extern \"C\" %s\n{\n", szFunctionSig );
//
// Reference the global variables declared above. This
// causes fixups (relocations) to be generated.
//
for ( j = 0; j < nGlobalVariablesPerFunction; j++ )
fprintf( pFileCPP, " g_var_n%u_%u = %s;\n", i, j, szBaseFunctionSig );
//
// Close the function definition with a '}'
//
fprintf( pFileCPP, "}\n\n" );
// Emit a prototype for the function to the associated .H file
fprintf( pFileHeader, "extern \"C\" %s;\n", szFunctionSig );
// Emit a call to the function from the main EXE's source file
fprintf( pMainSource, " %s();\n", szBaseFunctionSig );
}
fclose( pFileCPP );
fclose( pFileHeader );
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -