开始想在MFC程序中使用cygwin64的库(静态库, 动态库(静态包含), 动态库(动态调用)).
做实验之前, 想想只要将gnu的功能封装成库(只需要封装成接口, 逻辑部分可以不动或轻微修改), 给自己工程用, 前景多美好.
现实很骨感. 试过了, 都不行, 走弯路了.
cygwin64官方文档上, 关于DLL这块, 也是给可以替换CRTinit这种VS工程用的. 如果像MFC这种框架型的工程, 根本没办法替换CRTInit的操作.
总之, 想将gnu实现包进自己工程用, 和cygwin64官方的思路就相违背. 做这种实验, 吃苦头也就是水到渠成的了.
网上关于cygwin64DLL给VS工程的资料不多, 说来说去, 都是围着官方文档在转.
这个根本就编译不过, 因为编译出来的cygwin64库还有依赖的cygwin64底层实现, 各种编译报错.
这个可以编译过, 但是运行时, 如果在DLL函数中使用了cygwin64的函数(e.g. fopen), 虽然不报错, 可是直接不好使, 文件都打不开(文件句柄为空). 原因是, cygwindll初始化无效引起的.
在LoadLIbrary()就会报错, LoadLibrary都没执行完.
无源码调试看了一下调用链.
可以看到, LoadLibray()时, 会进入DLL入口函数, 然后会调用cywin1_cygwin_dll_init(), 这个初始化函数会失败, 然后走到assert报错
我开始要做cygwin64DLL的原因: 因为调用批处理时候, 总是会出dos窗口. 因为这个程序是基于以前的实现堆出来的. 以前那个程序就在调用批处理时, 会不断的弹dos窗口. 这次功能行代码写完了, 就想将这个问题搞掉, 要不不像个程序啊(用户都会说这个dos弹窗问题).
然后去做cygwin64的DLL(顺便学了一下CMake的初级用法[CMake官方前4课], 用CMake来做linux程序构建的脚本, 不用自己去写Makefile了), 尝试给MFC-EXE用. 用了一个星期, 怎么玩cygwin64工程, 已经清楚了.
但是做好的cygnwin64DLL无法给MFC用.
然后思路又回到隐藏dos窗口上, 看了一些资料, 人家说确实可以调用批处理(.bat)时隐藏dos窗口, 那我的实现咋不行呢?
对了一下, 自己改了参数, CreateProcess()的参数5, 加了CREATE_NEW_CONSOLE, 有了这个参数, 就无法隐藏dos窗口.去掉这个就好了.
用了一个星期, 没有搞出新解决方法, 然后发现自己实现写错了, 还是挺难受的. 这不被自己玩了么?
毕竟cygwin64官方的目的是为了将linux/gnu工程移植到window, 让linux/gnu工程代码不改或少改.
如果主程序(非cygwin64工程)想用cygwin64工程的功能, 还是进行进程隔离来使用cygwin64工程输出, 这个也是最简单的方法.
毕竟大多数人的主程序也不可能是cygwin64的工程.
cygwin64官方也没考虑让cygwin64的工程输出能包含进其他程序.
BOOL COrderProcBase::executeCommandLine(CString cmdLine, DWORD& exitCode)
{
PROCESS_INFORMATION processInformation = {
0 };
STARTUPINFO startupInfo = {
0 };
memset(&startupInfo, 0, sizeof(STARTUPINFO));
GetStartupInfo(&startupInfo); // 可以得到以下3个信息, .cb不用自己填写了, .lpDesktop可以得到主程序的桌面位置
/*
cb 104 unsigned long
+ lpReserved 0x0000016952ea535c L"" wchar_t *
+ lpDesktop 0x0000016952ea533c L"Winsta0\\Default" wchar_t *
+ lpTitle 0x0000016952ea5212 L"D:\\...\\xParser.exe" wchar_t *
其他值还是0
*/
startupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_HIDE;
startupInfo.lpReserved = NULL;
startupInfo.cbReserved2 = 0;
startupInfo.lpReserved2 = NULL;
// startupInfo.cb = sizeof(startupInfo);
int nStrBuffer = cmdLine.GetLength();
// printf("%ws\n", cmdLine.GetString());
// !!! 如果参数5加了 CREATE_NEW_CONSOLE, 就会出现dos窗口
// cmdLine.GetBuffer(), cmdLine.GetBuffer(nStrBuffer) 返回的指针地址都一样
BOOL result = CreateProcess(NULL, cmdLine.GetBuffer(nStrBuffer),
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW /* | CREATE_NEW_CONSOLE */,
NULL, NULL, &startupInfo, &processInformation);
cmdLine.ReleaseBuffer();
if (!result) {
// CreateProcess() failed
// Get the error from the system
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
// Display the error
CString strError = (LPTSTR)lpMsgBuf;
TRACE(_T("::executeCommandLine() failed at CreateProcess()\nCommand=%s\nMessage=%s\n\n"), cmdLine, strError);
// Free resources created by the system
LocalFree(lpMsgBuf);
// We failed.
return FALSE;
}
else {
// Successfully created the process. Wait for it to finish.
WaitForSingleObject(processInformation.hProcess, INFINITE);
// Get the exit code.
result = GetExitCodeProcess(processInformation.hProcess, &exitCode);
// Close the handles.
CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);
if (!result) {
// Could not get exit code.
TRACE(_T("Executed command but couldn't get exit code.\nCommand=%s\n"), cmdLine);
return FALSE;
}
// We succeeded.
return TRUE;
}
}
在做动态载入DLL时, 翻出以前在开源工程基础上改的实现, 还是那么好用.
作为研发, 平时做些奇怪没用的小实验, 只要归档了, 以后还是能用上的. 力气不白费.
修正了原版9个参数的动态调用函数定义.
增加了10~12个参数的动态函数定义.
#ifndef __LATE_LOAD__H__
#define __LATE_LOAD__H__
#if _MSC_VER > 1000
#pragma once
#endif
#include <windows.h>
#include <crtdbg.h>
/**
* @note LostSpeed modify at 2011_1127_0327
* update to fit unicode
* fix error on LATELOAD_FUNC_9_VOID
* add LATELOAD_FUNC_10, LATELOAD_FUNC_11, LATELOAD_FUNC_12
* add LATELOAD_FUNC_11_VOID, LATELOAD_FUNC_11_VOID, LATELOAD_FUNC_12_VOID
*/
/*
Module : LateLoad.h
Purpose: I was tired of constantly re-writing LoadLibrary & GetProcAddress code,
over & over & over again. So I created a series of macros that will
define & create a wrapper class to do it all for me.
This is NOT an end-all-be-all solution for loading DLLs. This is just a
handy lightweight helper when you would use LoadLibrary/GetProcAddress.
For more information on DLLs, check out MSDN.
This was inspired by my own need, as well as a nice little MSDN article
titled "DLLs the Dynamic Way" by "MicHael Galkovsky"
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndllpro/html/dlldynamic.asp
Unfortunatly, there was no source to go with the article. So, I wrote this
version quite a bit differently.
Author : Copyright (c) 2004 by Jason De Arte, All Rights Reserved.
Site : http://1001010.com/code/
License: Use it however you like as a compiled portion of your product(s).
Don't be a jerk by claiming the it as your own.
Usage : The following will declare the class "CUser32Wrapper" that will load
function pointer(s) from USER32.DLL. Those function names will become
member function(s) of the newly created class.
LATELOAD_BEGIN_CLASS(CUser32Wrapper,user32,FALSE)
LATELOAD_FUNC_0(NULL,HCURSOR,WINAPI,GetCursor)
LATELOAD_FUNC_1(NULL,HANDLE,WINAPI,NonExistantFunction,BOOL)
LATELOAD_END_CLASS()
// The above statements will auto-generate a class that functionaly equivalent to...
class CUser32Wrapper : public CLateLoadBase
{
public:
BOOL Is_GetCursor();
HCURSOR WINAPI GetCursor();
BOOL Is_NonExistantFunction();
HANDLE WINAPI NonExistantFunction();
};
// And usage is even easier
CUser32Wrapper uw;
HCURSOR h = uw.GetCursor();
// And for DLLs missing a function export, you can still use the member function!
uw.NonExistantFunction(true);
// It will just return the default non-existant value in the definition
// To determine if the funtion was imported, use the "BOOL Is_<FunctionName>();" member
Is_NonExistantFunction();
// If it exists, it will return TRUE. False if it does not exist
-------------------------------------------
Let's look at the various defines that are used...
LATELOAD_BEGIN_CLASS(CUser32Wrapper,user32,FALSE)
CUser32Wrapper - the class that will be created
user32 - the library that will be loaded
FALSE - determines if "FreeLibrary()" will be called in the destructor.
LATELOAD_FUNC_0(NULL,HCURSOR,WINAPI,GetCursor)
NULL - if the ProcAddress was not loaded, this value is returned in the call to that func
HCURSOR - the return type for the function
WINAPI - function calling convention
GetCursor - the exported function
LATELOAD_FUNC_1 (up to _9)
Identical to LATELOAD_FUNC_0, except it allows 1-9 parameters to the function
LATELOAD_FUNC_0_ (up to _9)
Same as before, but for use with NULL return types
LATELOAD_END_CLASS()
finalizes the class declaration
-------------------------------------------
History:
2004.Feb.29.JED - Created
*/
//
// Used for keeping track
//
enum ImportedProcState
{
ipsUnknown = 0, // No attempts to load the Proc have been made yet
ipsMissing, // GetProcAddress failed to find the exported function
ipsAvailable, // the Proc is Ready & Available for use
ips_MAX
};
#ifndef NO_VTABLE
# if _MSC_VER > 1000
# define NO_VTABLE __declspec(novtable)
# else
// 2004.Feb.29.JED - Note to self, find out what is appropriate under non-msvc compilers
//# define NO_VTABLE
# endif //_MSC_VER
#endif
//
// Declaration for the utility base class, not intended for non-inherited use.
//
class NO_VTABLE CLateLoadBase
{
//
// Why no v-table?
// 1) not needed
// 2) reduces code size
// 3) LATELOAD_BEGIN_CLASS calls ZeroMemory to blank out all the derived function
// pointers & ImportedProcState memeber variables - in the process the vtable
// will get blanked out.
// 4) This class is not intended to be instantiated on its own.
// 5) Makes it so that using this class on its own will cause an Access Violation
//
protected:
HMODULE m_module; // Handle to the DLL
DWORD m_dwLoadLibError; // If there was an error from LoadLibrary
BOOL m_bManaged; // FreeLibrary in the destructor?
LPTSTR m_pszModule; // The name of the module, handy for first-use loading
/*****************************************************************************
* NAME:
* CLateLoadBase::dll_LoadLibrary
*
* DESCRIPTION:
* Loads the dll.
*
*******************************************************************************/
protected:
BOOL dll_LoadLibrary(LPCTSTR pszLibrary, BOOL bDoItNow)
{
//
// Make a record of the DLL name
//
if( !m_pszModule )
{
if( pszLibrary && *pszLibrary)
{
int nLen = lstrlen(pszLibrary);
m_pszModule = new TCHAR[nLen+2];
if( m_pszModule )
{
ZeroMemory( m_pszModule, sizeof(TCHAR)*(nLen+2) );
lstrcpy(m_pszModule,pszLibrary);
}
else
{
_ASSERT(!"CLateLoadBase::dll_LoadLibrary - Unable to allocate memory for a string!");
}
}
else
{
_ASSERT(!"CLateLoadBase::dll_LoadLibrary - We need a valid pszLibrary string");
}
}
// Nothing to do?
if( m_module )
return TRUE;
// Should we do this later?
if( !bDoItNow )
return FALSE;
// Load the DLL
m_dwLoadLibError = 0;
m_module = ::LoadLibrary(pszLibrary);
if( m_module )
return TRUE;
// Unable to load it, find out why
m_dwLoadLibError = GetLastError();
// We rely on the last error being not equal to zero on LoadLibrary failure.
// So, in the off chance it IS zero, we set it to a non-zero value.
// Tip: According to MSDN, Bit 29 in Get/SetLastError logic is reserved for Application
// defined error codes. No system level error codes should have this bit set.
if( !m_dwLoadLibError )
{
_ASSERT(!"Wow, that should NOT have happened! Could you tell JED how you did it?");
m_dwLoadLibError = 0x20000000;
}
return FALSE;
}
/*****************************************************************************
* NAME:
* CLateLoadBase::dll_GetProcAddress
*
* DESCRIPTION:
* Loads the function pointer from the DLL
*
*******************************************************************************/
protected:
FARPROC dll_GetProcAddress(LPCSTR pszFunctionName, ImportedProcState& ips)
{
FARPROC pfn = NULL;
ips = ipsUnknown;
// Does the DLL still need to be loaded?
if( !m_module && m_pszModule && *m_pszModule &&
0 == m_dwLoadLibError // There is no reason to attempt to load the DLL more than once
)
{
dll_LoadLibrary(m_pszModule,TRUE);
}
if( m_module )
{
pfn = ::GetProcAddress(m_module,pszFunctionName);
if( pfn )
ips = ipsAvailable;
else
ips = ipsMissing;
}
return pfn;
}
/*****************************************************************************
* NAME:
* CLateLoadBase::~CLateLoadBase
*
* DESCRIPTION:
* Description goes here...
*
*******************************************************************************/
public:
~CLateLoadBase()
{
if( m_bManaged && m_module )
::FreeLibrary(m_module);
m_module = NULL;
m_bManaged = FALSE;
if( m_pszModule )
delete m_pszModule;
m_pszModule = NULL;
}
/*****************************************************************************
* NAME:
* CLateLoadBase::dll_GetLoadError
*
* DESCRIPTION:
* If LoadLibrary failed, returns the error code.
* If there was no error, returns zero
*
*******************************************************************************/
public:
DWORD dll_GetLoadError()
{
return m_dwLoadLibError;
}
/*****************************************************************************
* NAME:
* CLateLoadBase::dll_IsLoaded
*
* DESCRIPTION:
* Is the DLL loaded?
*
*******************************************************************************/
public:
BOOL dll_IsLoaded()
{
return NULL!=m_module;
}
/*****************************************************************************
* NAME:
* CLateLoadBase::dll_GetModuleName
*
* DESCRIPTION:
* return the name of the module loaded
*
*******************************************************************************/
public:
LPCTSTR dll_GetModuleName()
{
return (LPCTSTR)m_pszModule;
}
};
//--------------------------------------------------------------------------------------
//
// Start of macros
//
//--------------------------------------------------------------------------------------
//
// Start, Declares the name of the class
//
// ClassName = the name of the class
// ModuleName = the DLL name
// bLoadDllNow = if true, the DLL will be loaded in the constructor.
// if false, it will ONLY be loaded when any bound function is first used
// bManaged = if true, FreeLibrary will be called in the destructor
//
#define LATELOAD_BEGIN_CLASS(ClassName,ModuleName,bLoadDllNow,bManaged) \
class ClassName : public CLateLoadBase \
{
\
public:\
ClassName()\
{
\
/*Automagicaly blank out all the function pointers and ImportedProcState member vars*/ \
/*that will be declared in following LATELOAD_FUNC_* declarations, very handy. */ \
ZeroMemory(static_cast<ClassName*>(this),sizeof(ClassName)); \
m_bManaged = bManaged; \
/*and load the DLL*/ \
dll_LoadLibrary(_T(#ModuleName),bLoadDllNow); \
}
//
// Function Declaration, Zero Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
//
// A function prototype that looked like...
// typedef BOOL (CALLBACK* SOMETHING)();
// or
// BOOL CALLBACK Something();
//
// Would be changed to...
// LATELOAD_FUNC_0(0,BOOL,CALLBACK,Something)
//
// If "Something" could not be loaded, and it was called - it would return 0
//
#define LATELOAD_FUNC_0(ErrorResult,ReturnType,CallingConv,FuncName) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName() \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(); \
}
//
// Function Declaration, One Parameter, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
// A function prototype that looked like...
// typedef BOOL (CALLBACK* SOMETHING)(BOOL);
// or
// BOOL CALLBACK Something(BOOL bEnable);
//
// Would be changed to...
// LATELOAD_FUNC_1(0,BOOL,CALLBACK,Something,BOOL)
//
// If "Something" could not be loaded, and it was called - it would return 0
//
#define LATELOAD_FUNC_1(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1); \
}
//
// Function Declaration, Two Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
// A function prototype that looked like...
// typedef BOOL (CALLBACK* SOMETHING)(BOOL,INT);
// or
// BOOL CALLBACK Something(BOOL bEnable, INT nNum);
//
// Would be changed to...
// LATELOAD_FUNC_2(0,BOOL,CALLBACK,Something,BOOL,INT)
//
// If "Something" could not be loaded, and it was called - it would return 0
//
#define LATELOAD_FUNC_2(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2); \
}
//
// Function Declaration, Three Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_3(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3); \
}
//
// Function Declaration, Four Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_4(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4); \
}
//
// Function Declaration, Five Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_5(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4,p5); \
}
//
// Function Declaration, Six Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_6(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4,p5,p6); \
}
//
// Function Declaration, Seven Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_7(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7); \
}
//
// Function Declaration, Eight Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_8(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8); \
}
//
// Function Declaration, Nine Parameters, returns a value
//
// ErrorResult, Default return value if the function could not be loaded & it is called anyways
// ReturnType, type of value that the function returns
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_9(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8,ParamType9 p9) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8,p9); \
}
#define LATELOAD_FUNC_10(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8,ParamType9 p9,ParamType10 p10) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10); \
}
#define LATELOAD_FUNC_11(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10,ParamType11) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10,ParamType11); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8,ParamType9 p9,ParamType10 p10,ParamType11 p11) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11); \
}
#define LATELOAD_FUNC_12(ErrorResult,ReturnType,CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10,ParamType11,ParamType12) \
protected: \
typedef ReturnType(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10,ParamType11,ParamType12); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
ReturnType FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8,ParamType9 p9,ParamType10 p10,ParamType11 p11,ParamType12 p12) \
{
\
if( !Is_##FuncName() ) \
return ErrorResult; \
return m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12); \
}
//
// Function Declaration, Zero Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
//
// A function prototype that looked like...
// typedef VOID (CALLBACK* SOMETHING)();
// or
// VOID CALLBACK Something();
//
// Would be changed to...
// LATELOAD_FUNC_0_VOID(CALLBACK,Something)
//
#define LATELOAD_FUNC_0_VOID(CallingConv,FuncName) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName() \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(); \
}
//
// Function Declaration, One Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
// A function prototype that looked like...
// typedef VOID (CALLBACK* SOMETHING)(BOOL);
// or
// VOID CALLBACK Something(BOOL bEnable);
//
// Would be changed to...
// LATELOAD_FUNC_1_VOID(CALLBACK,Something,BOOL)
//
#define LATELOAD_FUNC_1_VOID(CallingConv,FuncName,ParamType1) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1); \
}
//
// Function Declaration, Two Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
// A function prototype that looked like...
// typedef VOID (CALLBACK* SOMETHING)(BOOL,INT);
// or
// VOID CALLBACK Something(BOOL bEnable, INT nNumber);
//
// Would be changed to...
// LATELOAD_FUNC_2_VOID(CALLBACK,Something,BOOL,INT)
//
#define LATELOAD_FUNC_2_VOID(CallingConv,FuncName,ParamType1,ParamType2) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2); \
}
//
// Function Declaration, Three Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_3_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3); \
}
//
// Function Declaration, Four Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_4_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4); \
}
//
// Function Declaration, Five Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_5_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4,p5); \
}
//
// Function Declaration, Six Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_6_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4,p5,p6); \
}
//
// Function Declaration, Seven Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_7_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7); \
}
//
// Function Declaration, Eight Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_8_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8); \
}
//
// Function Declaration, Nine Parameters, returns nothing
//
// CallingConv, Calling convention of the function
// FuncName, Name of the function
// ParamN types of the function parameters
//
#define LATELOAD_FUNC_9_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8,ParamType9 p9) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8,p9); \
}
#define LATELOAD_FUNC_10_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8,ParamType9 p9,ParamType10 p10) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10); \
}
#define LATELOAD_FUNC_11_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10,ParamType11) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10,ParamType11); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8,ParamType9 p9,ParamType10 p10,ParamType11 p11) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11); \
}
#define LATELOAD_FUNC_12_VOID(CallingConv,FuncName,ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10,ParamType11,ParamType12) \
protected: \
typedef void(CallingConv * TYPE_##FuncName)(ParamType1,ParamType2,ParamType3,ParamType4,ParamType5,ParamType6,ParamType7,ParamType8,ParamType9,ParamType10,ParamType11,ParamType12); \
TYPE_##FuncName m_pf##FuncName; \
ImportedProcState m_ips##FuncName;\
public: \
BOOL Is_##FuncName() \
{
\
if(ipsUnknown == m_ips##FuncName) \
m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, m_ips##FuncName); \
return(ipsAvailable == m_ips##FuncName); \
} \
void FuncName(ParamType1 p1,ParamType2 p2,ParamType3 p3,ParamType4 p4,ParamType5 p5,ParamType6 p6,ParamType7 p7,ParamType8 p8,ParamType9 p9,ParamType10 p10,ParamType11 p11,ParamType12 p12) \
{
\
if( Is_##FuncName() ) \
m_pf##FuncName(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12); \
}
//
// End of the class
//
#define LATELOAD_END_CLASS() };
#endif //__LATE_LOAD__H__
更多【c++-MFC工程中无法使用cygwin64的库】相关视频教程:www.yxfzedu.com