Friday, March 30, 2012

Pass pointer as parameter to method invoked using reflection

Recently, I was trying to execute one of the CLR internal private static method declared in System.Math class. This method excepts double pointer but Method.Invoke accepts object array and double pointer cannot be type as object.

Background:
I wanted to customize rounding functionality of double. So I used reflector and identified the code used for rounding. This code uses CLR internal SplitFractionDouble method that can return splitted decimal part and removes the decimal part from the value at double pointer passed as parameter. So in my custom logic I wanted to call that method but the problem is how to pass double pointer as object in the Invoke method. Following are the steps to resolve that issue and was able to call the method successfully.

1. Start unsafe block or add the logic in unsafe function

2. Getting method info of CLR internal method. Here parameter type is added as a typeoff(double*).
MethodInfo methodInfo = typeof(Math).GetMethod("SplitFractionDouble", BindingFlags.NonPublic | BindingFlags.Static, Type.DefaultBinder,new[] { typeof(double*) },null);

3. Call the method. Here most important thing is that address of value is typecasted into int and then further type casted into IntPtr. IntPtr can be used for any kind of references.
 var result = (double)methodInfo.Invoke(null, new object[] { (IntPtr)(int)&value});

Tuesday, September 20, 2011

dos batch script to remove last line


::-----bo Batchl....
@echo off & setlocal
 
Set FirstLine=True
 
:: Delete the existing file so that it can be created with latest data
IF EXIST ggg.txt (del /Q ggg.txt)
 
For /F "tokens=*" %%i in ('findstr /V "Text in last line" "InputFile.txt"') do call :doSomething "%%i"
goto :eof
 

:: This function will check if it is the first line to be printed or it will print new line before printing next line
:doSomething
Set ThisLine="%~1"
 
IF %FirstLine%==True (
Set FirstLine=False
) ELSE (
echo. >> OutputFile.txt
)
call :printLine %ThisLine%
goto :eof
 
:: This function prints a text without next line
:printLine
for %%a in ("%~1") do (
echo/|set /p =%%a
) >> OutputFile.txt
 
:eof
::-----eo Batch....  

Friday, February 11, 2011

Execute DDL in remote database from other users

Following tutorial will explain you the process of executing DDL statements on remote database by users other then schema owner with permission control. I created this when we were not allowed to use schema owner as application user but need to execute DDL's securely from other user.
1.  Create procedure in remote database that accepts query as parameter
CREATE OR REPLACE PROCEDURE EXECUTEDDL
(ddl_in in varchar2)
IS
BEGIN
EXECUTE IMMEDIATE (ddl_in);
END;
/
2. Create private database link in source database if not existing
CREATE DATABASE LINK <Link name> CONNECT TO <Schema name> IDENTIFIED BY <password> USING '<Service name>';
3. Create synonym in source database for the procedure created in remote database. I prefer creating synonyms to access any objects of remote database so that code can look clean and changes in remote database objects/schema name can easily be applied in the source database by updating synonyms.
CREATE OR REPLACE SYNONYM <Synonym name> FOR <remote schema name>.EXECUTEDDL@<remote database link >
4. Create wrapper procedure in source database which will call remote procedure via synonym.
CREATE OR REPLACE PROCEDURE EXECUTEDDL_REMOTE
(ddl_in in varchar2)
IS
BEGIN
<Synonym name>(ddl_in);
END;
/
5. Grant permission to other users to execute new procedure
GRANT EXECUTE ON EXECUTEDDL_REMOTE TO <User name>