Welcome! Please see the About page for a little more info on how this works.

0 votes
in ClojureCLR by

When doing (from C#)

RT.load( "my.util", true );

and having directory containing my\util.clj on CLOJURE_LOAD_PATH I get

System.IO.FileNotFoundException: Could not locate my.util.clj.dll or my.util.clj on load path.

I believe the latter is wrong - it should be looking for my\util.clj on load path?

Also, there is a problem with compiled assemblies whose namespace contains -'s. For example, if I have compiled namespace myns.foo-bar (in file myns\foo_bar.clj) it produces myns.foo_bar.clj.dll. If I try to load it like so:

RT.load( "myns.foo-bar", true );

System.IO.FileNotFoundException: Could not locate myns.foo-bar.clj.dll or myns.foo-bar.clj on load path.

I think RT.load should "know" that compiling a namespace with - character in it is mapped to _ on the corresponding dll or source file name.

5 Answers

0 votes
by

Comment made by: dmiller

One should not be calling RT.load directly. Most functions in the RT namespace are not for C1. code doing Clojure interop.

In the case of RT.load specifically, internally it is called only once, during system init, to load clojure/core.

Instead of direct calls, use the new interop capability to call from C1. to Clojure functions.
The Clojure.var method is actually clojure.clr.api.Clojure.var

IFn load= Clojure.var("clojure.core", "+");
load.invoke("my.util");

See if this works for you.

0 votes
by

Comment made by: akaranta

Ah, ok, I thought RT's methods were public API, I think I picked this usage up from an example somewhere and it seemed to work. And mostly does.

I'm currently using Clojure-CLR 1.5.0 and class clojure.clr.api.Clojure does not seem to exist. I take it is new in 1.6.0? What is the recommended way to load a namespace / var in 1.5.0?

0 votes
by

Comment made by: dmiller

That class is indeed new in 1.6.0. In 1.50, you can do exactly what clojure.clr.api does:

    private static Symbol asSym(object o)
    {
        String str = o as String;
        Symbol s = str != null ? Symbol.intern(str) : (Symbol)o;
        return s;
    }

    public static IFn var(object qualifiedName)
    {
        Symbol s = asSym(qualifiedName);
        return var(s.Namespace, s.Name);
    }
    public static IFn var(object ns, object name)
    {
        return Var.intern(asSym(ns), asSym(name));
    }

If you have two strings, one for namespace, one for name, this simplifies to

Var x = clojure.lang.Var.intern(ns,name);
0 votes
by

Comment made by: akaranta

For some reason clojure.core/load does not seem to be able to find the given namespace (i.e. the corresponding .dll) whereas RT.load does find it.

Do I need to perform some extra dance steps to tell clojure.core/load where to look for the dlls? Preferably no environment variables like CLOJURE_LOAD_PATH involved. In practice they will be in the same directory as other dlls in my app (and I can easily programmatically find that out where that is if need be). Unfortunately it is neither the current dir nor the dir of the executing assembly.

BTW, automatically adding the location of Clojure.dll to the load path would likely solve at least my issue with clojure.core/load and I would guess it to be generally useful, too.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJCLR-32 (reported by alex+import)
...