First steps into Clojure-CLR, how to import a DLL

792 views
Skip to first unread message

Magnus Therning

unread,
Mar 14, 2014, 10:56:50 AM3/14/14
to cloju...@googlegroups.com
I'm a complete newbie to Clojure and also pretty much to MS
C#/CLR/VS2013/etc, so please bear with me here.

I have a .NET DLL (FTD2XX_NET.dll) which I have successfully dropped
into a C# project. I just "Add Reference...", navigate to the DLL,
choose it, add "using FTD2XX_NET;" (the namespace in the DLL), and
then I can start using the stuff in there. Easy peasy.

How do I achieve the same thing in a Clojure project?

Here's what doesn't seem to work ;)

Add the reference to the DLL as per the C# project. Then modify the
namespace in my 'program.clj' to read

~~~~
(ns program
(:import FTD2XX_NET)
(:gen-class))
~~~~

Neither does this work:

~~~~
(ns program
(:import FTD2XX_NET.FTDI)
(:gen-class))
~~~~

In both cases I get an error at compile time saying that

Error 1 (1,1,8,2): System.NullReferenceException: Object
reference not set to an instance of an object.
at clojure.lang.Util.NameForType(Type t)
at clojure.lang.Namespace.importClass(Type t)
at program$loading__16927__auto____61.invoke()
at clojure.lang.AFn.ApplyToHelper(IFn fn, ISeq argList)
at clojure.lang.AFn.applyTo(ISeq arglist)
at clojure.lang.CljCompiler.Ast.InvokeExpr.Eval(), compiling:
(tmp34A7.clj:1:1) C:\devo\ClojureTest\ClojureTest\program.clj 1
1

/M

--
Magnus Therning OpenPGP: 0xAB4DFBA4
email: mag...@therning.org jabber: mag...@therning.org
twitter: magthe http://therning.org/magnus

Antti Karanta

unread,
Mar 15, 2014, 11:52:37 AM3/15/14
to cloju...@googlegroups.com

Hi,


There functions are direct correspondents to their namesakes in System.Reflection.Assembly (http://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx)

The easiest to use might be (assembly-load-from "path\\to\\your\\assembly.dll")

You need to load the assembly before the ns declaration (assuming that is where you make the imports).

OTOH you may also use lein-clr (https://github.com/kumarshantanu/lein-clr), see my previous question about loading assemblies on this forum.


      ::Antti::

 

Magnus Therning

unread,
Mar 28, 2014, 6:17:24 AM3/28/14
to Antti Karanta, cloju...@googlegroups.com
On Sat, Mar 15, 2014 at 4:52 PM, Antti Karanta <antti....@gmail.com> wrote:
>
> Hi,
>
> Please see https://github.com/clojure/clojure-clr/wiki/Loading-assemblies
>
> There functions are direct correspondents to their namesakes in
> System.Reflection.Assembly
> (http://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx)
>
> The easiest to use might be (assembly-load-from
> "path\\to\\your\\assembly.dll")
>
> You need to load the assembly before the ns declaration (assuming that is
> where you make the imports).


I think I also need to make some other configuration changes in order
for it to work:

- with `(assembly-load-from "\\devo\\ClojureTest\\lib\\FTD2XX_NET.dll")` I get

"(NotSupportedException An attempt was made to load an assembly
from a network location which would have caused the assembly to be
sandboxed in previous versions of the .NET Framework. This release of
the .NET Framework does not enable CAS policy by default, so this load
may be dangerous. If this load is not intended to sandbox the
assembly, please enable the loadFromRemoteSources switch. See
http://go.microsoft.com/fwlink/?LinkId=155569 for more information.
[trace missing]"

- with `(assembly-load-from "lib\\FTD2XX_NET.dll")` I get

"(FileNotFoundException Could not load file or assembly
'file:///C:\Users\magnust\AppData\Local\Temp\lib\FTD2XX_NET.dll' or
one of its dependencies. The system cannot find the file specified.
System.Reflection.RuntimeAssembly._nLoad (:0)"

Both when trying to load the project into the REPL. In the first case
I did follow the link but after 10 minutes of reading and following
links I still don't know WHERE to change the runtime settings. In the
second case I was sort of hoping that the REPL would execute with a
CWD of the location of my project (or the solution), but that doesn't
seem to be the case.

Hints on where to find more info on how to fix this is most welcome.

/M

Antti Karanta

unread,
Mar 31, 2014, 1:47:50 AM3/31/14
to cloju...@googlegroups.com, Antti Karanta


perjantai, 28. maaliskuuta 2014 12.17.24 UTC+2 Magnus Therning kirjoitti:

I think I also need to make some other configuration changes in order
for it to work:

- with `(assembly-load-from "\\devo\\ClojureTest\\lib\\FTD2XX_NET.dll")` I get

    "(NotSupportedException An attempt was made to load an assembly
from a network location which would have caused the assembly to be
sandboxed in previous versions of the .NET Framework. This release of
the .NET Framework does not enable CAS policy by default, so this load
may be dangerous. If this load is not intended to sandbox the
assembly, please enable the loadFromRemoteSources switch. See
http://go.microsoft.com/fwlink/?LinkId=155569 for more information.
[trace missing]"

I have seen this on a fríend's box but it does not reproduce on mine so I have not figured it out. The only difference between our environments that I can think of is that he is using Windows 8 and I have Windows 7. Which one do you have?

 
- with `(assembly-load-from "lib\\FTD2XX_NET.dll")` I get

    "(FileNotFoundException Could not load file or assembly
'file:///C:\Users\magnust\AppData\Local\Temp\lib\FTD2XX_NET.dll' or
one of its dependencies. The system cannot find the file specified.
System.Reflection.RuntimeAssembly._nLoad (:0)"

Please try 
(System.IO.File/Exists path) ;; with the same path. 
If that returns true but assembly-load-from fails then it's likely that one of the dependencies of that assembly can't be found. You can investigate them e.g. with ilspy (http://ilspy.net/).

 
Both when trying to load the project into the REPL.  In the first case
I did follow the link but after 10 minutes of reading and following
links I still don't know WHERE to change the runtime settings.  In the
second case I was sort of hoping that the REPL would execute with a
CWD of the location of my project (or the solution), but that doesn't
seem to be the case.

I guess that by project / solution you are referring to VSClojure Visual Studio project? I have no experience with that but with leiningen clr (https://github.com/kumarshantanu/lein-clr) things work fairly smootly.



          ::Antti::


 

Magnus Therning

unread,
Apr 2, 2014, 12:07:17 PM4/2/14
to Antti Karanta, cloju...@googlegroups.com
On Sun, Mar 30, 2014 at 10:47:50PM -0700, Antti Karanta wrote:
>perjantai, 28. maaliskuuta 2014 12.17.24 UTC+2 Magnus Therning kirjoitti:
>>
>>
>> I think I also need to make some other configuration changes in order
>> for it to work:
>>
>> - with `(assembly-load-from "\\devo\\ClojureTest\\lib\\FTD2XX_NET.dll")` I
>> get
>>
>> "(NotSupportedException An attempt was made to load an assembly
>> from a network location which would have caused the assembly to
>> be sandboxed in previous versions of the .NET Framework. This
>> release of the .NET Framework does not enable CAS policy by
>> default, so this load may be dangerous. If this load is not
>> intended to sandbox the assembly, please enable the
>> loadFromRemoteSources switch. See
>> http://go.microsoft.com/fwlink/?LinkId=155569 for more
>> information. [trace missing]"
>
> I have seen this on a fríend's box but it does not reproduce on mine
> so I have not figured it out. The only difference between our
> environments that I can think of is that he is using Windows 8 and I
> have Windows 7. Which one do you have?

I'm on Windows 7.

>> - with `(assembly-load-from "lib\\FTD2XX_NET.dll")` I get
>>
>> "(FileNotFoundException Could not load file or assembly
>> 'file:///C:\Users\magnust\AppData\Local\Temp\lib\FTD2XX_NET.dll'
>> or one of its dependencies. The system cannot find the file
>> specified. System.Reflection.RuntimeAssembly._nLoad (:0)"
>
> Please try (System.IO.File/Exists path) ;; with the same path. If
> that returns true but assembly-load-from fails then it's likely that
> one of the dependencies of that assembly can't be found. You can
> investigate them e.g. with ilspy (http://ilspy.net/).

I think the issue here is with my expectations on VSClojure :( See
more below.

>> Both when trying to load the project into the REPL. In the first case
>> I did follow the link but after 10 minutes of reading and following
>> links I still don't know WHERE to change the runtime settings. In the
>> second case I was sort of hoping that the REPL would execute with a
>> CWD of the location of my project (or the solution), but that doesn't
>> seem to be the case.
>
> I guess that by project / solution you are referring to VSClojure
> Visual Studio project? I have no experience with that but with
> leiningen clr (https://github.com/kumarshantanu/lein-clr) things
> work fairly smootly.

Yes, I'm using Visual Studio (2013) with the VSClojure addon. The
idea I had was to be able to use clojure-clr largely for the REPL to
play and experiment within a large-ish C# solution. Maybe even sneak
in some clojure under the radar at some point too.

What I did expect was that adding the reference in the
solution/project would have the effect that the REPL's context changed
and that loading assemblies would be a breeze after that. So far it
looks like my expectation was a little too high.

I have the impression that leiningen is designed to be used
stand-alone, i.e. not as a part of a Visual Studio solution. Is that
pretty much the case or do I have it completely wrong?

/M

--
Magnus Therning OpenPGP: 0xAB4DFBA4
email: mag...@therning.org jabber: mag...@therning.org
twitter: magthe http://therning.org/magnus

Any fool can write code that a computer can understand. Good programmers
write code that humans can understand.
-- Martin Fowler

Antti Karanta

unread,
Apr 3, 2014, 3:01:02 AM4/3/14
to cloju...@googlegroups.com, Antti Karanta


keskiviikko, 2. huhtikuuta 2014 19.07.17 UTC+3 Magnus Therning kirjoitti:
 
I have the impression that leiningen is designed to be used
stand-alone, i.e. not as a part of a Visual Studio solution.  Is that
pretty much the case or do I have it completely wrong?

  I am using it from command line and am not aware of any visual studio integration. It is pretty trivial, though, to add calls to leiningen as project pre- or post build step. This does not solve your assembly reference problems - you still have to programmatically ensure they are loaded before referring to them in your clojure code. 

I made some utility functions for myself to be able to do something like this before the namespace declaration (assemblies containing imported classes need to be loaded before the imports are "executed").

(require '[nerom [assemblyutils :as assembly]])

(assembly/require-assembly "clrzmq")

(ns xxx.yyy

  It's not general purpose as it contains some references to our particular paths in our development environment but it should be pretty easy for you to come up with something similar.


         ::Antti::

 
Reply all
Reply to author
Forward
0 new messages