Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
p6api.cpp
#if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN 1
# include <windows.h>
# define DLLHANDLE HMODULE
# define LOADERLIB "p6loader.dll"
# define LOADLIB(fn) LoadLibraryA((fn))
# define LOADSYMBOL(h,s) GetProcAddress((HMODULE)(h),(s))
# define FREELIB(h) FreeLibrary((HMODULE)(h))
#else
# include <string.h> // memcpy()
# include <dlfcn.h> // dlopen() etc.
# include <unistd.h> // readlink()
# define DLLHANDLE void*
# define LOADERLIB "libp6loader.so"
# define LOADLIB(fn) dlopen((fn),RTLD_NOW)
# define LOADSYMBOL(h,s) dlsym((h),(s))
# define FREELIB(h) !dlclose((h))
#endif
#include <stdio.h>
#include <stdlib.h> // getexecname() on solaris
#include "p6err.h" // Error and type definitions
#include "p6comdef.h" // [p6]COM definitions
#include "p6errorinfo.h" // Definition only, not supported by p6Loader
#include "p6runtimeapi.h" // Platform runtime API definitions
#include "p6comhlpr.h" // [p6]COM helper macros
#undef P6ASSERT
#define P6ASSERT(x)
#include "p6comptr.h" // Smart COM pointer, ASSERTs disabled
#include "p6runtimeif.h" // P6Platform's runtime COM API interface definitions
#include "p6datastream.h" // p6IDataStream interface definition
#include "p6loader.h" // Standalone Component Loader definitions
using namespace P6R;
DLLHANDLE ghDll = NULL;
P6INITIALIZELOADER gp6InitializeLoader = NULL;
P6CLEANUPLOADER gp6CleanupLoader = NULL;
P6CREATEINSTANCE gp6CreateInstance = NULL;
P6CREATECRYPTOINSTANCE gp6CreateCryptoInstance = NULL;
P6GETRUNTIMEIFACE gp6GetRuntimeIface = NULL;
P6GETDIRECTORY gp6GetDirectory = NULL;
P6ERRTOSTR gp6ErrToStr = NULL;
P6ERRTOWSTR gp6ErrToWStr = NULL;
P6ATOMICINC32 gp6AtomicInc32 = NULL;
P6ATOMICDEC32 gp6AtomicDec32 = NULL;
P6TRACEADDREF gp6TraceAddref = NULL;
P6TRACERELEASE gp6TraceRelease = NULL;
static P6R::P6ERR getModuleDir(P6CHAR *pBuffer,P6SIZE cBuffer)
{
P6ERR err = eOk;
if(!pBuffer || !cBuffer)
return eInvalidArg;
pBuffer[0] = '\0';
#if defined(_WIN32)
if(0 != ::GetModuleFileNameA(NULL,pBuffer,(DWORD)cBuffer)) {
P6CHAR *pTmp = pBuffer;
P6CHAR *pszEnd = NULL;
while(*pTmp) {
if('\\' == *pTmp) *pTmp = '/';
pTmp++;
}
pszEnd = strrchr(pBuffer,'/');
if(NULL != pszEnd) *pszEnd = '\0';
}
else err = eFail;
#elif defined(__SUNPRO_CC)
const P6CHAR *pszExecName = NULL;
if(NULL != (pszExecName = getexecname())) {
P6CHAR *pszEnd = NULL;
if('/' != *pszExecName) {
P6UINT32 offset = 0;
getcwd(pBuffer,cBuffer);
strcat(pBuffer,"/");
strcat(pBuffer,pszExecName);
}
else {
strcat(pBuffer,pszExecName);
}
pszEnd = strrchr(pBuffer,'/');
if(NULL != pszEnd) *pszEnd = '\0';
}
else err = eFail;
#elif defined(__linux__)
if(-1 != readlink("/proc/self/exe",pBuffer,cBuffer-1)) {
P6CHAR *pszEnd = NULL;
pszEnd = strrchr(pBuffer,'/');
if(NULL != pszEnd) *pszEnd = '\0';
err = P6R::eOk;
}
#endif
return err;
}
static P6R::P6ERR loadSymbols()
{
P6ERR err = eDllNotFound;
P6CHAR szLib[P6MAXPATH] = {0};
if(P6SUCCEEDED(getModuleDir(&szLib[0],P6CHARCNT(szLib)))) {
strcat(&szLib[0],"/");
strcat(&szLib[0],LOADERLIB);
if(NULL != (ghDll = LOADLIB(&szLib[0]))) {
gp6InitializeLoader = (P6INITIALIZELOADER) LOADSYMBOL(ghDll,"p6InitializeLoader");
gp6CleanupLoader = (P6CLEANUPLOADER) LOADSYMBOL(ghDll,"p6CleanupLoader");
gp6CreateInstance = (P6CREATEINSTANCE) LOADSYMBOL(ghDll,"p6CreateInstance");
gp6CreateCryptoInstance = (P6CREATECRYPTOINSTANCE) LOADSYMBOL(ghDll,"p6CreateCryptoInstance");
gp6GetRuntimeIface = (P6GETRUNTIMEIFACE) LOADSYMBOL(ghDll,"p6GetRuntimeIface");
// Note that these functions can be called prior to p6InitializeLoader() and/or if it fails
gp6GetDirectory = (P6GETDIRECTORY) LOADSYMBOL(ghDll,"p6GetDirectory");
gp6ErrToStr = (P6ERRTOSTR) LOADSYMBOL(ghDll,"p6ErrToStr");
gp6ErrToWStr = (P6ERRTOWSTR) LOADSYMBOL(ghDll,"p6ErrToWStr");
gp6AtomicInc32 = (P6ATOMICINC32) LOADSYMBOL(ghDll,"p6AtomicInc32");
gp6AtomicDec32 = (P6ATOMICDEC32) LOADSYMBOL(ghDll,"p6AtomicDec32");
gp6TraceAddref = (P6TRACEADDREF) LOADSYMBOL(ghDll,"p6TraceAddref");
gp6TraceRelease = (P6TRACERELEASE) LOADSYMBOL(ghDll,"p6TraceRelease");
if(gp6InitializeLoader && gp6CleanupLoader && gp6CreateInstance && gp6GetRuntimeIface && \
gp6ErrToStr && gp6ErrToWStr && gp6AtomicInc32 && gp6AtomicDec32) {
err = eOk;
}
else {
if(!gp6InitializeLoader) printf("ERROR: Symbol Not Found [ p6InitializeLoader ]\n");
if(!gp6CleanupLoader) printf("ERROR: Symbol Not Found [ p6CleanupLoader ]\n");
if(!gp6CreateInstance) printf("ERROR: Symbol Not Found [ p6CreateInstance ]\n");
if(!gp6GetRuntimeIface) printf("ERROR: Symbol Not Found [ p6GetRuntimeIface ]\n");
if(!gp6GetDirectory) printf("ERROR: Symbol Not Found [ gp6GetDirectory ]\n");
if(!gp6ErrToStr) printf("ERROR: Symbol Not Found [ p6ErrToStr ]\n");
if(!gp6ErrToWStr) printf("ERROR: Symbol Not Found [ p6ErrToWStr ]\n");
if(!gp6AtomicInc32) printf("ERROR: Symbol Not Found [ p6AtomicInc32 ]\n");
if(!gp6AtomicDec32) printf("ERROR: Symbol Not Found [ p6AtomicDec32 ]\n");
if(!gp6TraceAddref) printf("ERROR: Symbol Not Found [ p6TraceAddref ]\n");
if(!gp6TraceRelease) printf("ERROR: Symbol Not Found [ p6TraceRelease ]\n");
err = eNotFound;
}
}
else {
#if defined(_WIN32)
printf("ERROR: Failed to dynamially load '%s' [ %x ]\nERROR: OS Error: %x\n",&szLib[0],err,::GetLastError());
#else
printf("ERROR: Failed to dynamially load '%s' [ %x ]\nERROR: OS Error: %s\n",&szLib[0],err,dlerror());
#endif
}
}
return err;
}
static void unloadSymbols()
{
if(NULL != ghDll) {
(void) FREELIB(ghDll);
}
}
extern "C" P6R::P6ERR p6InitializeLoader(P6R::p6IDataStream *pLogSink,P6R::P6INT32 nVerbosity,P6SCLF fFlags)
{
P6ERR err;
if(P6SUCCEEDED(err = loadSymbols())) {
if(P6FAILED(err = gp6InitializeLoader(pLogSink,nVerbosity,fFlags))) {
P6CHAR szErr[256] = {0};
printf("ERROR: p6InitializeLoader() Failed [ %s ]\n",gp6ErrToStr(err,&szErr[0],P6CHARCNT(szErr)));
}
}
return err;
}
{
P6ERR err = gp6CleanupLoader();
unloadSymbols();
return err;
}
extern "C" P6R::P6ERR p6GetRuntimeIface(const P6R::IID &iid,P6R::P6VOID **ppIface)
{
if(!gp6GetRuntimeIface) return eNotInitialized;
return gp6GetRuntimeIface(iid, ppIface);
}
extern "C" P6R::P6ERR p6CreateInstance(P6R::p6ICom *pOuter,const P6R::CID &cid,const P6R::IID &iid,P6R::P6VOID **ppIface)
{
if(!gp6CreateInstance) return eNotInitialized;
return gp6CreateInstance(pOuter,cid,iid,ppIface);
}
extern "C" P6R::P6ERR p6CreateCryptoInstance(const P6R::CID& cid,const P6R::IID& iid,P6R::P6VOID** ppIface)
{
if(!gp6CreateCryptoInstance) return eNotInitialized;
return gp6CreateCryptoInstance(cid,iid,ppIface);
}
extern "C" P6R::P6ERR p6GetDirectory(P6DIRS nDir,P6R::P6WCHAR* pBuffer,P6R::P6SIZE cBuffer,P6R::P6SIZE* pcWritten)
{
if(!gp6GetDirectory) return eNotInitialized;
return gp6GetDirectory(nDir,pBuffer,cBuffer,pcWritten);
}
extern "C" P6R::P6CHAR* p6ErrToStr(P6R::P6ERR err,P6R::P6CHAR *pszBuffer,P6R::P6SIZE cBuffer)
{
if(!gp6ErrToStr) return NULL;
return gp6ErrToStr(err,pszBuffer,cBuffer);
}
extern "C" P6R::P6WCHAR* p6ErrToWStr(P6R::P6ERR err,P6R::P6WCHAR *pszBuffer,P6R::P6SIZE cBuffer)
{
if(!gp6ErrToWStr) return NULL;
return gp6ErrToWStr(err,pszBuffer,cBuffer);
}
extern "C" P6R::P6INT32 p6AtomicInc32(P6R::P6INT32 volatile *pVar)
{
if(!gp6AtomicInc32) return 0;
return gp6AtomicInc32(pVar);
}
extern "C" P6R::P6INT32 p6AtomicDec32(P6R::P6INT32 volatile *pVar)
{
if(!gp6AtomicDec32) return 0;
return gp6AtomicDec32(pVar);
}
extern "C" P6R::P6ERR p6TraceAddref(const P6R::P6CHAR *pszClassname,P6R::P6UINT32 cClassSize,P6R::P6VOID *classAddr,P6R::P6INT32 refCount,P6R::P6UINT32 *pSerialNumber)
{
if(!gp6TraceAddref) return eNotInitialized;
return gp6TraceAddref(pszClassname,cClassSize,classAddr,refCount,pSerialNumber);
}
extern "C" P6R::P6ERR p6TraceRelease(const P6R::P6CHAR *pszClassname,P6R::P6VOID *classAddr,P6R::P6INT32 refCount,P6R::P6UINT32 *pSerialNumber)
{
if(!gp6TraceRelease) return eNotInitialized;
return gp6TraceRelease(pszClassname,classAddr,refCount,pSerialNumber);
}
extern "C" P6API P6R::P6ERR p6Assert(const P6R::P6WCHAR *pszExpr,const P6R::P6CHAR *pszFile,P6R::P6UINT32 nLine)
{
return eOk;
}