Sunday, November 7, 2010

jni4net 0.8.1 - bugfix release

  • Fixed memory leak reported by Jaco Ackermann
  • Included improved CLR detection contributed by Leonid Bogdanov
Download 0.8.1 here

Thursday, September 23, 2010

Decomposition in functional languages

Got an idea: functions (in FP) could be composed similar was as components in OOP. For example with dependency injection. For components in OOP we use interfaces. For functions we could use delegates. To achieve decomposition and modularity.
I tried to find something about it. No luck. Probably because there are no functional programs big enough to need this ?
While searching for enterprise scale applications written in FP I found this list. Functional Programming in the Real World and this paper

I hope I just missed the killer application for FP, which would be big enough to deserve decomposition. Maybe someone could find me answer at stack overflow.

Tuesday, July 20, 2010

CLR 4.0 for Robocode

I finally got motivated by Justin and Jason to do something for Robocode .NET again. I upgraded it to jni4net 0.8. This means Robocode will prefer CLR 4.0 if installed and then will run robots written in C# 4.0 or F#. I also implemented Robocode Control API for .NET. I piggyback to Flemming's working branch, hope he will not kill me once he returns from holidays :-D

Download preview is there, Alpha quality.


I really like the syntax.
namespace SampleFs
open Robocode
type MyFirstRobot() = 
    inherit Robot()
    override robot.Run() = 
            while true do
    override robot.OnScannedRobot(evnt : ScannedRobotEvent) = 
    override robot.OnHitByBullet(evnt : HitByBulletEvent) = 
            robot.TurnLeft(90.0 - evnt.Bearing)

Sunday, May 30, 2010

Learning F# with Project Euler - day 2

Problem 4

open Microsoft.FSharp.Core.Operators
let findpalindrome xs ys =
    let separate s p = (s % (pown 10 (p+1))) - (s % (pown 10 p))
    let shiftl s p o = (separate s p) / (pown 10 (p-o))
    let shiftr s p o = (separate s p) * (pown 10 (o-p))
    let flip f = shiftl f 5 0 + shiftl f 4 1 + shiftl f 3 2 + shiftr f 2 3 + shiftr f 1 4 + shiftr f 0 5
    let findi xs y = xs |> Seq.filter( fun x -> (((x*y) = flip (x*y)) && (separate (x*y) 0 <> 0) ) ) |> x -> (x*y,x))
    ys |> Seq.collect(fun y -> (findi xs y)) |> Seq.maxBy(fun t -> fst(t))

findpalindrome [100..999][100..999]

Problem 5

let test = 
    let max = (primes 20 |> Seq.reduce(fun a c -> a*c))*8L*3L
    [1L..20L] |> Seq.filter(fun x -> (max % x) <> 0L)

Problem 6

let diff xs = 
    let sumsq = xs |> Seq.reduce(fun c a -> (a*a)+c)
    let sum = (xs |> Seq.reduce(fun c a -> (a+c)))
    let sqsum  = sum*sum
    sqsum  - sumsq

diff [1..100]

Problem 7

open Microsoft.FSharp.Core.Operators
let primesnth nthprime = 
    let maxPrime = 300000
    let pr : bool array = Array.zeroCreate maxPrime
    let mutable res = 0
    let mutable nth = 0
    let mutable cur=2
    while (nth < nthprime) do
        if not pr.[cur] then
            for wr in cur+cur .. cur .. maxPrime-1 do pr.[wr] <- true
            res <- cur
            nth <- nth + 1 
        cur <- cur + 1

primesnth 10001

Friday, May 28, 2010

Learning F# with

Wow, lot of fun with !

Problem 1

[1..999] |> Seq.filter( fun x -> (x % 3 = 0 || x % 5 = 0)) |> Seq.sum

Problem 2

let fib max = 
    let rec fibo a b max = 
        if b>= max then a :: [] else a :: fibo b (a+b) max
    fibo 1 2 max

fib 4000000 |> Seq.filter(fun x -> (x % 2 = 0)) |> Seq.toList|> Seq.sum

Problem 3

open Microsoft.FSharp.Math 
open System.Collections.Generic
let maxPrime:int= (int) (System.Math.Sqrt((float)600851475143I))
let primes maxPrime = 
    let pr : bool array = Array.zeroCreate maxPrime
    let res = new List()
    for cur in 2 .. maxPrime/2 do
        if not pr.[cur] then for wr in cur+cur .. cur .. maxPrime-1 do pr.[wr] <- true
    for cur in 1 .. maxPrime-1 do
        if not pr.[cur] then res.Add(new bigint(cur))

primes maxPrime |> 
    Seq.filter(fun x -> ((600851475143I % x) = 0I )) 
    |> fun x -> ((int)(x))) 
    |> Seq.max

Saturday, April 17, 2010

jni4net NOT yet on Mono & Linux

I started with investigations of support for Mono on x86. The key problem is different calling convention - cdecl. My current implementation of JniLocalHandle is build on top of assumption that small structures are put onto stack same way as scalar types. But that's not valid assumption, it works just for stdcall. cdecl allocates the structure on heap and passes just pointer to the structure, no matter how big the structure is. Why I created JniLocalHandle ? Because I wanted to make strongly typed difference between JniLocalHandle and JniGlobalHandle. We could drop it and use IntPtr in order to deal with this problem. It will impact all generated proxies on C# side.
There is another problem with cdecl, because I need to put
on any JNI delegate. Example is JNIEnv.AllocObject. I think I'll need to duplicate whole JNIEnv class in order to avoid condition for each call.
Last small problem is with JNI.Dll which has the main
[DllImport("jvm.dll", CallingConvention = CallingConvention.StdCall)]
, it must be duplicated as well, because there is on Linux.

Currently I don't hear from people that they need Mono/Linux support for jni4net. If you think you need it, please tell us the use case. I'm interested to hear why Mono support is worth of the effort. Till then I put it on ice.

jni4net version 0.8 for .NET 4.0

  • added support for CLR v 4.0
  • v40 is now loaded by default if it could be found. You could set the version explicitly with Bridge.setClrVersion()
  • #8 added BridgeSetup.AddJVMOption(string)
Download jni4net 0.8

Wednesday, March 3, 2010

jni4net 0.7.1 - small bugfix release

Bug fixes

  • [#7] - added ParPrimC2J(IntPtr)
  • [#5] - Reading Java home location from the Windows registry (Contributed by Martin Matula), BridgeSetup extended with JavaHome, and improved JavaHome auto detection
  • fixed missing assembly version for jni4net.n.*.dll

Thursday, February 25, 2010

Robocode with C++/CLI

Recently I spotted question if it's possible to create robot in C++. Here is the answer. Ok, I know, it's not like real C++ with pointers etc, this is managed version of C++, which is safe enough to be runnable in Robocode.
  • Download VS 2008 Express C++
  • Create new CLR-> Class Library (DLL) project
  • Go to project properties, Common Properties, Add New Reference, and add robocode.dll from lib folder of your robocode installation.
  • Go to project properties, Configuration properties, General, Common Language Runtime support and set it to Safe MSIL (/clrsafe)
  • Go to AssemblyInfo.cpp and delete line with [assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
  • Go to [myCppRobot].h and insert code below
  • Compile it, drop the DLL into Robocode and enjoy!
#pragma once
using namespace System;
using namespace Robocode;
namespace myCppR {
    public ref class MyCplusplusRobot : Robot {
        virtual void Run() override {
            while(true) {

Saturday, February 13, 2010

jni4net version 0.7 released

support for delegates and events

.NET events and delegates are supported by proxygen and runtime. From Java side they could be invoked with Invoke() method which has proper signature. Delegates could be also implemented on Java side, by usual anonymous class and passed back to CLR. So Java could subscribe to .NET events.
this.button1.addClick(new system.EventHandler(){
        public void Invoke(system.Object sender, system.EventArgs e){
Full code is in winforms sample, which is part of binaries.

Other changes

  • solved problem with spaces in path to dll/jar
  • assembly loading now uses or assembly name (breaking change)
  • static class is no longer found by name, attribute parameter added (breaking change)
Download there

Sunday, January 24, 2010

jni4net version 0.6 released

  • Implemented out and ref parameter from C#
  • DateTime.TryParse has second parameter 'out'. This is how to use it from Java:
    Out<DateTime> dt=new Out<DateTime>();
    if (DateTime.TryParse("2009-08-28",dt)){

  • Improved proxygen to not generate virtual method overrides
  • Eliminated lot of warnings in generated code
  • Strongly typed JNI references (this is breaking change, please regenerate your proxies)
  • Sun specific DirectBufferCleaner, which holds the reference to pinned buffer
  • Native methods unregistration when appdomain unloads
  • Switched off signed .jar, because it prevents other people generating (unsigned) proxies into same packages. For example java.util_
  • Possibility to specify alternate classloader
  • Declarative security for running in partially trusted environments
  • JVM exceptions are serializable for CLR binary serialization
Download there

Saturday, January 9, 2010

Robocode .NET - alpha bits

I'm proud to present working version of .NET Robocode for community testing. It took me almost exactly 2 years.


  • make sure you have .NET framework >= 2.0 installed on your windows box
  • backup your robocode home

Install and start


  • start your Visual Studio
  • open robots/samplescs/samplescs.csproj
  • or create project new and reference robocode.dll from libs\ (Robot API for .NET)
  • and code your own .NET robot :-D
Please try it and say what you think !

Known gaps

  • Robot API xml documentation is not yet ready
  • IGraphics/onPaint have just simple operations implemented
  • Robot could create unlimited threads, (but could not cause any harm to your computer)
  • jni4net 0.6 was not released public yet
  • Few unit tests still fail

These binaries above are 1.7.3, but that was just working number. We will merge it to trunk and release as 1.7.2 probably. Sources are in trunk already.