Wednesday, October 3, 2007

Playing with C++/CLI

Few things to note for comfort transition from C# to C++/CLI Pragmas
// use on base level, outside of namespace
#pragma unmanaged
#pragma managed

//Regions
#pragma region Helpers
#pragma endregion
Needed rotate, not just shift
//native
#define asm_ror(val, shift) __asm { ror val,shift }
#define asm_rol(val, shift) __asm { rol val,shift }

//managed
#define managed_ror(val, shift) val=((val>>shift)|(val<<(32-shift)))
#define managed_rol(val, shift) val=((val<<shift)|(val>>(32-shift)))
Nested namespaces
namespace Zamboch
{
 namespace Engine
 {
...
 }
}
Calling to native code and back to CLR
#pragma once

#include <vcclr.h>
using namespace System;
using namespace System::Runtime::InteropServices;


#pragma unmanaged

extern "C" { 
    typedef void* (__stdcall *myCALLBACK)(int smallIndex);
}

// static pointer to managed function
myCALLBACK fnGetDataPage;

void foo()
{
    //Calling back to CLR
    void* dtpage=fnGetDataPage(1);
}

#pragma managed

ref class Class1
{
public:
    // testing entrypoint
    static void Main()
    {
        //Call to native
        foo();
    }

    //callback implementation
    static void* GetDataPage(int smallIndex)
    {
        void* dtpage = NULL;
        return dtpage;
    }

private:
#pragma region Delegate initialization

    delegate void* myCALLBACKDelegate(int smallIndex);

    static GCHandle gch;

    //static constructor, initialize delegate here
    static Class1()
    {
        myCALLBACKDelegate^ fp=gcnew myCALLBACKDelegate(GetDataPage);
        gch = GCHandle::Alloc(fp);
        fnGetDataPage = static_cast<myCALLBACK>(Marshal::GetFunctionPointerForDelegate(fp).ToPointer());
    }

#pragma endregion

};

No comments: