Monday, December 27, 2010

Basic pattern for Events in C++/CLI

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr;

public ref class CManaged 
{
public:
    delegate bool CallbackHandler(int);
    // For user to register handler
    event CallbackHandler^ OnCallback
    {
        void add(CallbackHandler^ handler)
        {
            lock lockEvents(this);
            m_callback = (CallbackHandler^) m_callback->Combine(m_callback, handler);
        }
        void remove(CallbackHandler^ handler)
        {
            lock lockEvents(this);
            m_callback = (CallbackHandler^) m_callback->Remove(m_callback, handler);
           
        }
    protected:
        bool raise(int n)
        {
            bool ret = true;
            for each(CallbackHandler^ handler in m_callback->GetInvocationList()){
                ret = ret && handler->Invoke(n);
            }
            return ret;
        }
    }

private:
    CallbackHandler^ m_callback;

public:
    CManaged()
    {
    }
    ~CManaged()
    {
    }

    bool InvokeCallback(int n)
    {
        if(m_callback)
            return m_callback->Invoke(n);
        return false;
    }

    bool Callback(int n)
    {
        printf("%d\n", n);
        return true;
    }
};

int main(array ^args)
{
    CManaged^ c = gcnew CManaged;
    c->OnCallback +=  gcnew CManaged::CallbackHandler(c, &CManaged::Callback);
    c->OnCallback +=  gcnew CManaged::CallbackHandler(c, &CManaged::Callback);

    c->InvokeCallback(1);
    c->InvokeCallback(2);
    return 0;
}

Wrapping C/C++ callback in C++/CLI


/**
 * Unmanaged part
 */

typedef boost::function UnmanagedCallback;
typedef bool (__stdcall *CallbackTypeProxy)(int);

class CUnmanaged {
private:
    boost::function m_callback;
public:
    CUnmanaged(const boost::function & callback) : m_callback(callback)
    {
    }

    bool Callback(int n)
    {
        return m_callback(n);
    }
};

/**
 * Managed part
 */

using namespace System::Runtime::InteropServices;

public ref class CManaged 
{
private:
    delegate bool CallbackHandler(int);
    CallbackHandler^ m_callback;
    CUnmanaged * m_object;

    bool Callback(int n)
    {
        printf("%d\n", n);
        return true;
    }
public:
    CManaged()
    {
        m_callback = gcnew CallbackHandler(this, &CManaged::Callback);
        System::IntPtr ip = Marshal::GetFunctionPointerForDelegate(m_callback);
        CallbackTypeProxy cb = static_cast(ip.ToPointer());

        m_object = new CUnmanaged(boost::bind(cb, _1));
    }
    ~CManaged()
    {
         delete m_object;
    }

    bool InvokeCallback(int n)
    {
        return m_object->Callback(n);
    }
};

int main(array ^args)
{
    CManaged c;
    c.InvokeCallback(1);
    c.InvokeCallback(2);
    return 0;
}


Friday, December 10, 2010

Windows Session, Desktop, and Station

http://blogs.technet.com/b/markrussinovich/archive/2010/02/24/3315174.aspx



http://blogs.technet.com/b/askperf/archive/2007/07/24/sessions-desktops-and-windows-stations.aspx

A session consists of all of the processes and other system objects that represent a single user’s logon session. 
These objects include all windows, desktops and windows stations.
A windows station is basically a security boundary to contain desktops and processes.


So, a session may contain more than one Windows Station and each windows station can have multiple desktops.


http://www.brianbondy.com/blog/id/100/

http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx

Use sysinternals psexec to spawn process in another session, e.g.
% psexec -s -i 3 E:\__tmp\CUDA\Benchmark\Release\benchmark -r

How psexec works

Friday, November 19, 2010

GPU Programming

Memory transfer: http://wiki.accelereyes.com/wiki/index.php?title=GPU_Memory_Transfer
CUDA introduction: http://www.drdobbs.com/architecture-and-design/207200659
CUDA as a service or accessed from remote desktop
CUDA Training Resources: http://developer.nvidia.com/object/cuda_training.html

How to create CUDA project on VS2008 http://stackoverflow.com/questions/2046228/how-do-i-start-a-new-cuda-app-in-visual-studio-2008

How to set Visual Assist X to handle new file extensions: http://www.wholetomato.com/forum/topic.asp?TOPIC_ID=5481

GPU-based Effects on WPF

    Tuesday, September 21, 2010

    Aliasing symbol names during Link time

    Reference: see  VC/crt/src/crtdll.c




      /*
      * _pRawDllMain MUST be an extern const variable, which will be aliased to
      * _pDefaultRawDllMain if no real user definition is present, thanks to the
      * alternatename directive.
      */
    
    extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID);
    extern BOOL (WINAPI * const _pDefaultRawDllMain)(HANDLE, DWORD, LPVOID) = NULL;
    #if defined (_M_IX86)
    #pragma comment(linker, "/alternatename:__pRawDllMain=__pDefaultRawDllMain")
    #elif defined (_M_IA64) || defined (_M_AMD64)
    #pragma comment(linker, "/alternatename:_pRawDllMain=_pDefaultRawDllMain")
    #else  /* defined (_M_IA64) || defined (_M_AMD64) */
    #error Unsupported platform
    #endif  /* defined (_M_IA64) || defined (_M_AMD64) */
    
    
    Example:
    1. Inside a static lib A, put the following
    extern "C" int xxx = 2;
    2. Inside an EXE which links A, put the following
    extern "C" int a = 4;
    #pragma comment(linker, "/alternatename:_xxx=_a")
    

    In this case "xxx" will be resolved as 2. Now how if we remove the line inside static-lib A. In this case the linker will replace "xxx" with "a", which is equal to 4.


    BTW, don't forget to put addition "_" in front of symbol name inside #pragma comment directives. It is necessary to follow "C" name decoration. See http://msdn.microsoft.com/en-us/library/deaxefa7.aspx.

    Coding Standard

    http://www.possibility.com/Cpp/CppCodingStandard.html

    boost::spirit

    http://stackoverflow.com/questions/924642/boost-spirit-headers-deprecated

    Friday, September 3, 2010

    Visual Studio Extension (Add-Ins)

    windows management console (msc) list

    http://searchwarp.com/swa217012.htm


    • certmgr.msc Certificate Manager
    • ciadv.msc Indexing Service
    • comexp.msc Component services
    • compmgmt.msc Computer management
    • devmgmt.msc Device Manager 
    • dfrg.msc Defragment
    • diskmgmt.msc Disk Management
    • fsmgmt.msc Folder Sharing Management
    • eventvwr.msc Event Viewer
    • gpedit.msc Group Policy 
    • iis.msc Internet Information Services
    • lusrmgr.msc Local Users and Groups
    • mscorcfg.msc .Net configurations
    • ntmsmgr.msc Removable Storage
    • perfmon.msc Performance Manager
    • rsop.msc RSoP - Resultant Set of Policy
    • secpol.msc Local Security Policy
    • services.msc System Services 
    • wmimgmt.msc Windows Management Instrumental

    Thursday, August 5, 2010

    Wednesday, July 7, 2010

    Reading const

    From: http://stackoverflow.com/questions/487048/difference-between-const-declarations-in-c

    I always keep in mind this easy rule: const always applies on the thing at the immediate left of it, if this thing doesn't exists, it applies to the thing on the immediate right.



    Wednesday, May 12, 2010

    Monday, May 10, 2010

    Direct2D

    Direct2D can be used on Session 0 !!
    http://blogs.msdn.com/b/directx/archive/2009/09/11/using-direct2d-for-server-side-rendering.aspx

    but only with software rendering :(
    http://en.wikipedia.org/wiki/Direct2D

    Direct2D can minimize CPU usage and utilise hardware rendering on a graphics card that supports Direct3D 10.1 and/or Direct3D 10 Feature Level 9 with WDDM 1.1 drivers, falling back to software rendering using WARP10 in situations when hardware is not available, such as session 0, and for remote server-side rendering. Direct2D performance and memory usage scale linearly with primitive counts in both software and hardware.

    Direct2D vs. GDI

    Surface sharing among various technologies

    Example on how to draw bitmap using Direct2D

    Writing DPI aware application

    Friday, February 26, 2010

    MFC DLLs: Regular vs. Extension

    Dll Version of MFC
    http://msdn.microsoft.com/en-us/library/hw85e4bb(v=VS.90).aspx

    http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c4017


    MFC Extension DLL -> doesn't have _USRDLL, have DllMain generated, do not have CWinApp instance instantiated

    MFC Regular DLL -> have _USRDLL, doesn't have DllMain generated, have CWinApp instantiated

    When exporting a function with extern "C"inside an MFC Regular DLL dynamically linked to MFC, we need to put AFX_MANAGE_STATE macro as follows


    extern "C" __declspec(dllexport) int AddFive(int x)
    {
         AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
         return x + 5;
    }
    How to provide DllMain for MFC Regular DLL

    VS2008 DLL Guide


    Special care need to be taken when using Regular DLL to access external resources. See the below article: