"Paul" <
XXXX@XXXXX.COM >wrote in message
I suggest you get rid of that and use the WINAPI macro instead. Tha is how
DllEntryPoint() and DllMain() arte meant to be used, ie:
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID
lpvReserved)
Now, with that said, BCB DLLs use DllEntryPoint() by default, not DllMain().
Are you trying to create a VC++ style DLL?
Quote
#ifdef CTS_BCB_DLL_STDCALL
unsigned long __stdcall
#else
unsigned long __cdecl
#endif
CtsSysLogCreate ( const char * In_ServerAddress,
const unsigned long In_ServerPort,
void** Out_ClientHandle )
I strongly suggest that you __stdcall for all of your functions
unconditionally. The only time you should ever use __cdecl is when you need
to use variable-length parameter lists via the '...' keyword, which you are
not using. Besides, not all environments support __cdecl anyway, so if you
want your DLL to be portable then you should always use __stdcall.
I suggest that you use this code instead (untested):
TThreadList *SysLogs = NULL;
BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID
lpvReserved)
{
switch( fwdreason )
{
case DLL_PROCESS_ATTACH:
{
SysLogs = NULL;
try
{
SysLogs = new TThreadList;
}
catch (const Exception &) {}
catch (...) {}
if( !SysLogs )
return FALSE;
break;
}
case DLL_PROCESS_DETACH:
{
if( SysLogs != NULL )
{
TList *Logs = SysLogs->LockList();
try
{
for(int i = 0; i < Logs->Count; ++i)
delete static_cast<TIdSysLog*>(Logs->Items[i]);
Logs->Clear();
}
__finally
{
SysLogs->UnlockList();
}
delete SysLogs;
SysLogs = NULL;
}
break;
}
}
return TRUE;
}
ULONG __stdcall CtsSysLogCreate(const char* In_ServerAddress, const
USHORT In_ServerPort, void** Out_ClientHandle)
{
if( (!strlen(In_ServerAddress)) || (!In_ServerPort) ||
(!Out_ClientHandle) || IsBadWritePtr(*Out_ClientHandle, sizeof(void*) )
return CTSSYSLOG_RESULT_PARAMETER_INVALID;
try
{
*Out_ClientHandle = NULL;
TIdSysLog* IdSysLog = new TIdSysLog(NULL);
try
{
IdSysLog->Host = In_ServerAddress;
IdSysLog->Port = In_ServerPort;
SysLogs->Add(IdSysLog);
// no need to set the Active property here. All that does
is
// ensures that the TIdSysLog's Binding property has a valid
// TIdSocketHandle available. When TIdSysLog::SendMsg()
// is called later, it does the same thing anyway, so it is
redundant
// to activate the TIdSysLog at this time...
*Out_ClientHandle = IdSysLog;
}
catch(const Exception &)
{
delete IdSysLog;
IdSysLog = NULL;
throw;
}
return CTSSYSLOG_RESULT_OK;
}
catch (const Exception &) {}
catch (...) {}
return CTSSYSLOG_RESULT_UNKNOWN_EXCEPTION;
}
ULONG __stdcall CtsSysLogDestroy(void* In_ClientHandle)
{
try
{
TIdSysLog *IdSysLog = static_cast<TIdSysLog*>(In_ClientHandle);
bool Found = false;
TList *Logs = SysLogs->LockList();
try
{
if( List->Remove(IdSysLog)>-1 )
{
Found = true;
delete IdSysLog;
}
}
__finally
{
SysLogs->UnlockList();
}
return Found ? CTSSYSLOG_RESULT_OK :
CTSSYSLOG_RESULT_INVALID_PARAM;
}
catch (const Exception &) {}
catch (...) {}
return CTSSYSLOG_RESULT_UNKNOWN_EXCEPTION;
}
TIdSyslogSeverity GetSeverity(const ULONG In_Severity)
{
switch( In_Severity )
{
case CTS_SYSLOG_slEmergency:
return slEmergency;
case CTS_SYSLOG_slAlert:
return slAlert;
case CTS_SYSLOG_slCritical:
return slCritical;
case CTS_SYSLOG_slError:
return slError;
case CTS_SYSLOG_slWarning:
return slWarning;
case CTS_SYSLOG_slNotice:
return slNotice;
case CTS_SYSLOG_slInformational:
return slInformational;
case CTS_SYSLOG_slDebug:
default:
return slDebug;
}
}
TIdSyslogFacility GetFacility(const ULONG In_Facility)
{
switch( In_Facility )
{
case CTS_SYSLOG_sfKernel:
return sfKernel;
case CTS_SYSLOG_sfMailSystem:
return sfMailSystem;
case CTS_SYSLOG_sfSystemDaemon:
return sfSystemDaemon;
case CTS_SYSLOG_sfClockDaemonOne:
return sfClockDaemonOne;
case CTS_SYSLOG_sfClockDaemonTwo:
return sfClockDaemonTwo;
case CTS_SYSLOG_sfFTPDaemon:
return sfFTPDaemon;
case CTS_SYSLOG_sfSecurityOne:
return sfSecurityOne;
case CTS_SYSLOG_sfSecurityTwo:
return sfSecurityTwo;
case CTS_SYSLOG_sfSysLogInternal:
return sfSysLogInternal;
case CTS_SYSLOG_sfLogAlert:
return sfLogAlert;
case CTS_SYSLOG_sfLPR:
return sfLPR;
case CTS_SYSLOG_sfNNTP:
return sfNNTP;
case CTS_SYSLOG_sfUUCP:
return sfUUCP;
case CTS_SYSLOG_sfNTP:
return sfNTP;
case CTS_SYSLOG_sfLocalUseZero:
return sfLocalUseZero;
case CTS_SYSLOG_sfLocalUseOne:
return sfLocalUseOne;
case CTS_SYSLOG_sfLocalUseTwo:
return sfLocalUseTwo;
case CTS_SYSLOG_sfLocalUseThree:
return sfLocalUseThree;
case CTS_SYSLOG_sfLocalUseFour:
return sfLocalUseFour;
case CTS_SYSLOG_sfLocalUseFive:
return sfLocalUseFive;
case CTS_SYSLOG_sfLocalUseSix:
return sfLocalUseSix;
case CTS_SYSLOG_sfLocalUseSeven:
return sfLocalUseSeven;
case CTS_SYSLOG_sfUserLevel:
default:
return sfUserLevel;
}
}
ULONG __stdcall CtsSysLogSend(void* In_ClientHandle, const ULONG
In_Severity, const ULONG In_Facility, const char* In_Message)
{
try
{
TIdSysLog* IdSysLog = static_cast<TIdSysLog*>(In_ClientHandle);
bool Found = false;
TList *Logs = SysLogs->LockList();
try
{
if( List->IndexOf(IdSysLog)>-1 )
{
Found = true;
IdSysLog->SendMsg("TestApp", In_Message,
GetFacility(In_Facility), GetSeverity(In_Severity), true; 1234);
}
}
__finally
{
SysLogs->UnlockList();
}
return Found ? CTSSYSLOG_RESULT_OK :
CTSSYSLOG_RESULT_INVALID_PARAM;
}
catch (const Exception &) {}
catch (...) {}
return CTSSYSLOG_RESULT_UNKNOWN_EXCEPTION;
}
Gambit