Monday, August 30, 2010

Calling a function in a DLL from C# code

1. Analyze DLL's function entry point

a. Use "dumpbin.exe" to peek inside the dll's structure.



- We will use command "dumpbin.exe /EXPORT your_dll.dll"
e.g. dumpbin.exe /EXPORTS D:\myDLL\PiEstimatorDLL.dll

- It may be a good idea to write the output into a file
e.g. umpbin.exe /EXPORTS D:\myDLL\PiEstimatorDLL.dll >> dll_export.txt

- NOTE : dumpbin.exe should be installed with your Visual Studio by default.

b. Find function entry point from the output.



- Assume that we want to call PiEstimator.estimatePi() method in the given dll,
we should use "?estimatePi@PiEstimator@@SANH@Z" as the entry point for the function, as underlined in the above screen shot.

2. Use the DLL in your C# code

In your C# code, you should add "DllImport" to import and use your dll functions, such as the following.

...
[DllImport("PiEstimatorDll.dll", EntryPoint = "?estimatePi@PiEstimator@@SANH@Z"]
public static extern double estimatePi(int numIter);

....

double piEstimation = estimatePi(numIter);

...


- NOTE : you should set your PATH environment variable so that the compiler can look up your dll (e.g. PiEstimatorDLL.dll.) Otherwise, you shall give a full path to your dll in DllImport command.

Friday, August 27, 2010

Pi Estimation using Monte Carlo Method in C++ (Visual C++)


Here is C++ implementation of Pi Estimation using Monte Carlo Method.

Generating a uniformly distributed random number in C++ was quite a task. I think it's better to use a well-made library for random number generation. (e.g. Boost library)

a. header file

public class PiEstimator {
public:
PiEstimator(void);
~PiEstimator(void);
double estimatePi(int numIter);
};


b. cpp implementation file

#include "PiEstimator.h"
#include
#include
#include

unsigned time_seed() {
time_t now = time ( NULL );
unsigned char *p = (unsigned char *)&now;
unsigned seed = 0;
size_t i;

for ( i = 0; i < sizeof now; i++ )
seed = seed * ( UCHAR_MAX + 2U ) + p[i];

return seed;
}

PiEstimator::PiEstimator(void) {
srand ((unsigned)time_seed());
}

PiEstimator::~PiEstimator(void) {
}

double randomNumber() {
return (double)rand()/(double)RAND_MAX;
}

double getRandDistance() {
double x = randomNumber();
double y = randomNumber();
return sqrt(pow(x,2) + pow(y,2));
}

double PiEstimator::estimatePi(int numIter) {
int numHits = 0;
for (int i = 0; i < numIter; i++) {
if (getRandDistance() <= 1) {
numHits++;
}
}
double pi = 4 * (numHits / (double)numIter);
return pi;
}

Wednesday, August 25, 2010

Using DLL in Excel VBA macro

1. Hook up DLL with VBA

a. Start Excel and open up VBA Editor
- After starting your Excel file, press "Alt + F11" to start VBA editor

b. Add a module
- "Insert" -> "Module" to add a new module.

c. Write declaration code to hookup dll with VBA
- Declaring a VBA function to call a DLL goes like this.
[Public | Private] Declare Function name Lib "libname" [Alias "aliasname"] [([arglist])] [As type]

- In your Module file, add the following.


'Declare all the API-specific items Private to the module
Private Declare Function GetSystemMetrics Lib "user32" _
(ByVal nIndex As Long) As Long

Private Const SM_CXSCREEN = 0 'Screen width
Private Const SM_CYSCREEN = 1 'Screen height

'The width of the screen, in pixels
Public Function ScreenWidth() As Long
ScreenWidth = GetSystemMetrics(SM_CXSCREEN)
End Function

'The height of the screen, in pixels
Public Function ScreenHeight() As Long
ScreenHeight = GetSystemMetrics(SM_CYSCREEN)
End Function




2. Using VBA code in your excel.

Monday, August 02, 2010

Pi estimation with Monte Carlo Method in Python


The following page explains what Monte Carlo Method is in a very simple yet understandable way. It wasn't very difficult for me to figure it out so I guess it's not going to be too difficult for you, either!



The following is my implementation of pi estimation with Monte Carlo Method in Python.


#!/usr/bin/python

import random
import math

def get_dist ():
x = random.uniform(0,1)
y = random.uniform(0,1)
dist = math.sqrt(math.pow(x, 2) + math.pow(y, 2))
return dist


# number of hits / number of misses = ((1/4) * pi * sqrt(radius)) / sqrt(radius)
# pi = 4 * number of hits / number of misses

num_hits = 0
num_throws = 0
while 1:
num_throws += 1
# if distance from origin is <= 1, it's within the quadrant.
if (get_dist() <= 1):
num_hits += 1
pi = 4 * (num_hits / float(num_throws))
print "iteration #", num_throws, ":", pi