how can I build an assembly I can AddReference()?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

how can I build an assembly I can AddReference()?

Brandon Craig Rhodes
I am interested in whether Python for .NET can help me provide
third-party programmers with a way to write C# routines that will get
called from my Python application.  I was impressed earlier today with
how easily Python for .NET compiled for Python 2.6 and the most recent
Visual Studio release, so I set about trying to write a C# routine and
call it from inside of Python.

I have only gotten as far as trying to AddReference() my new DLL, but
have not been able to get it to succeed.

I first created a "Brandon.cs" file with this inside:

----------------------------------------
using System;
using System.Reflection;

[assembly:AssemblyVersion("1.0.0.0")]
[assembly:AssemblyDescription("The Brandon library")]
[assembly:AssemblyCompany("Rhodes Mill Studios, Inc.")]

namespace Brandon
{
   public static class BrandonClass
   {
      public static void Go()
      {
         Console.WriteLine("Hello, World!");
      }
   }
}
----------------------------------------

This was simple enough to compile with:

    csc /t:library Brandon.cs

which produced a "Brandon.dll" file.  Look at what happens if I then try
importing that DLL from Python for .NET:

    >>> import clr
    >>> print clr.FindAssembly('Brandon')
    C:\Users\brandon\dev\pythonnet\Brandon.dll
    >>> clr.AddReference('Brandon')
    ...
    System.IO.FileNotFoundException: Unable to find assembly 'Brandon'.
       at Python.Runtime.CLRModule.AddReference(String name) in c:\Users\brandon\dev\pythonnet\src\runtime\moduleobject.cs:line 370

You can see that, oddly enough, Python can find the assembly, but cannot
create a reference to it.  This error message also results, by the way,
if I compile "Brandon.cs" with a "/keyfile:..." option and run "gacutil
/i Brandon.dll" before trying to run my Python code.

I know that the step I am missing is probably blazingly obvious to those
who have been using Windows longer, :-) but I will very much appreciate
whomever who can point out what critical step I am missing in getting my
Python code to call C# code.  Other than this hangup, I'm impressed by
how quickly Python for .NET got me up and running!

--
Brandon Craig Rhodes   [hidden email]   http://rhodesmill.org/brandon
_________________________________________________
Python.NET mailing list - [hidden email]
http://mail.python.org/mailman/listinfo/pythondotnet
Reply | Threaded
Open this post in threaded view
|

Re: how can I build an assembly I can AddReference()?

dhirschfeld
Brandon Craig Rhodes <brandon@...> writes:

> I have only gotten as far as trying to AddReference() my new DLL, but
> have not been able to get it to succeed.
>
>     >>> import clr
>     >>> print clr.FindAssembly('Brandon')
>     C:\Users\brandon\dev\pythonnet\Brandon.dll
>     >>> clr.AddReference('Brandon')
>     ...
>     System.IO.FileNotFoundException: Unable to find assembly 'Brandon'.
>        at Python.Runtime.CLRModule.AddReference(String name) in
> c:\Users\brandon\dev\pythonnet\src\runtime\moduleobject.cs:line 370
>
> You can see that, oddly enough, Python can find the assembly, but cannot
> create a reference to it.

Works for me:


Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 0.10 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [2]: pwd
Out[2]: 'C:\\temp\\PythonDotNET'

In [3]: ls
 Volume in drive C has no label.
 Volume Serial Number is 90C1-4729

 Directory of C:\temp\PythonDotNET

28/05/2010  08:35    <DIR>          .
28/05/2010  08:35    <DIR>          ..
26/10/2009  14:03             5,632 FactoryPattern.dll
               1 File(s)          5,632 bytes
               2 Dir(s)  188,252,098,560 bytes free

In [4]: import clr

In [5]: clr.AddReference('FactoryPattern')
Out[5]: <System.Reflection.Assembly object at 0x03798DA0>


...but I was in the same directory as the dll. Are you in the same directory?
What happens if you try to put the full path? e.g.

clr.AddReference(r'C:\temp\PythonDotNET\FactoryPattern')

If that doesn't work does using Assembly.LoadFile work? e.g.

from clr import System
from System import Reflection
full_filename = r'C:\temp\PythonDotNET\FactoryPattern.dll'
Reflection.Assembly.LoadFile(full_filename)

HTH,
Dave





_________________________________________________
Python.NET mailing list - [hidden email]
http://mail.python.org/mailman/listinfo/pythondotnet
Reply | Threaded
Open this post in threaded view
|

Re: how can I build an assembly I can AddReference()?

Brandon Craig Rhodes
Dave Hirschfeld <[hidden email]> writes:

> Brandon Craig Rhodes <brandon@...> writes:
>
>>     >>> import clr
>>     >>> print clr.FindAssembly('Brandon')
>>     C:\Users\brandon\dev\pythonnet\Brandon.dll
>>     >>> clr.AddReference('Brandon')
>>     ...
>>     System.IO.FileNotFoundException: Unable to find assembly 'Brandon'.
>>        at Python.Runtime.CLRModule.AddReference(String name) in
>> c:\Users\brandon\dev\pythonnet\src\runtime\moduleobject.cs:line 370
>
> Works for me ... but I was in the same directory as the dll. Are you
> in the same directory?

Yes, I am in the same directory; and I just double-checked before
replying. :-)

> If that doesn't work does using Assembly.LoadFile work? e.g.
>
> from clr import System
> from System import Reflection
> full_filename = r'C:\temp\PythonDotNET\FactoryPattern.dll'
> Reflection.Assembly.LoadFile(full_filename)

Ah!  That gives a much more informative error message:

Traceback (most recent call last):
  File "test.py", line 28, in <module>
    Reflection.Assembly.LoadFile(r'C:\Users\brandon\dev\pythonnet\Brandon.dll')
System.BadImageFormatException: This assembly is built by a runtime newer than t
he currently loaded runtime and cannot be loaded. (Exception from HRESULT: 0x801
3101B)
   at System.Reflection.Assembly.nLoadFile(String path, Evidence evidence)
   at System.Reflection.Assembly.LoadFile(String path)

Well, drat.  A newer runtime?  So in response to this, I have just gone
through and removed all traces of earlier Visual Studios and .NET on my
computer, leaving only 2010 and 4.0 in my list of installed programs,
and then checked out a fresh copy of Python for .NET and rebuilt it with
"msbuild" and then tried again.  Unfortunately I get the same error
message.  Is the problem that stock Python 2.6 is built with an older
runtime than the one I am using to build my DLL?  What should I try
next?  Thanks for the help!

--
Brandon Craig Rhodes   [hidden email]   http://rhodesmill.org/brandon
_________________________________________________
Python.NET mailing list - [hidden email]
http://mail.python.org/mailman/listinfo/pythondotnet
Reply | Threaded
Open this post in threaded view
|

Re: how can I build an assembly I can AddReference()?

Brandon Craig Rhodes
Brandon Craig Rhodes <[hidden email]> writes:

> System.BadImageFormatException: This assembly is built by a runtime newer than t
> he currently loaded runtime and cannot be loaded. (Exception from HRESULT: 0x801
> 3101B)
>    at System.Reflection.Assembly.nLoadFile(String path, Evidence evidence)
>    at System.Reflection.Assembly.LoadFile(String path)

This afternoon I uninstalled Visual Studio 2010 from my laptop and
re-installed Visual Studio 2008, then rebuilt "Brandon.dll", in the
hopes that 2010 was simply too recent a version of Studio to be using
with the c:\python26 from the python.org page.  Sadly, I was wrong; I
still get the above error when trying to import the DLL.

--
Brandon Craig Rhodes   [hidden email]   http://rhodesmill.org/brandon
_________________________________________________
Python.NET mailing list - [hidden email]
http://mail.python.org/mailman/listinfo/pythondotnet
Reply | Threaded
Open this post in threaded view
|

Re: how can I build an assembly I can AddReference()?

Brandon Craig Rhodes
In reply to this post by Brandon Craig Rhodes
Aha!

I can now build my assembly successfully and import it into Python!

Upon closer inspection, I discovered that uninstalling Visual Studio
2010 did *not* actually remove the compilation subsystem I was using, it
turns out, from C:\Windows\Microsoft.NET\Framework\v4.0.30319.  And so
my DLL was still coming out based on a too-recent runtime version.

Once I replaced my %PATH% with:

    PATH=C:\Windows\Microsoft.NET\Framework\v3.5

and re-ran "csc /t:library Brandon.cs", I got a DLL that imports and
runs just fine from inside of Python!

So it was just my ignorance of how Windows development works, and of
which paths and installed components determine the runtime version of a
built component, that seems to have caused the problem.  This experience
over the last two days - of, in effect, staring at a bank of knobs and
blinking lights and having no idea which knobs will have what effects -
really helped me have sympathy as I was simultaneously answering some
questions from a friend who is trying to figure out how to compile
Python on a Mac when he has never dealt with "configure", "make", or
shared libraries before.  It made it easier to remember that what seemed
so sensible and obvious to me was a complete blank wall of ignorance and
mystery to him. :-)

--
Brandon Craig Rhodes   [hidden email]   http://rhodesmill.org/brandon
_________________________________________________
Python.NET mailing list - [hidden email]
http://mail.python.org/mailman/listinfo/pythondotnet
Reply | Threaded
Open this post in threaded view
|

Re: Problem debugging to python.runtime.dll

Barton
In reply to this post by Brandon Craig Rhodes
>  Vishal.Parikh wrote:
>>/
/>>/  We are actually using Python.Net with python 2.5 and I wanted to learn
/>>/  the internal architecture of the Python.Runtime.Dll. I have tried
/>>/  debugging the dll by attaching the process to python.exe but doesn't hit
/>>/  any break point. I don't know much about the compiler design and how it
/>>/  works internal but all I want is I should be able to debug how my C#
/>>/  instruction is getting executed using python.runtime.dll
/>>/
/

>/  /In the Debug Tab of the Properties dialog for your C# project choose "Start
>/  /external program" for the Start Action and select the normal CPython
>  executable - python.exe. In the "Command line arguments" put the full path
>  of the python script which calls the C# function you want to debug. If you
>  debug the project now it should run the python script and you should drop in
>  to the c# debugger at the breakpoint you set in the function called by the
>  Python script.
>
>  HTH,
>  Dave

It's been pretty quiet on the list lately, so I post a couple of helpful tips:

Instead of using the "normal CPython" executable, I find it useful to choose
[PathToSolution]/python.exe which is a Managed Code way of loading the pythonxx.dll
and allows you to step out of the interpreter main loop when your script exits.

Using a cool IDE (like Boa Constructor) which lets you set the interpreter, I
also choose [PathToSolution]/python.exe.  This makes running [PathToProject]/src/tests/runtests.py
(which imports the Pythnon.Test managed test assembly) a snap!

This all works thanks to the Post-build event command line of the projects:
Python.Runtime:
call "$(ProjectDir)buildclrmodule.bat" $(Platform) "$(ProjectDir)" "$(TargetDir)clr.pyd"
copy "$(TargetPath)" "$(SolutionDir)"
copy "$(TargetDir)*.pdb" "$(SolutionDir)"
copy "$(TargetDir)clr.pyd" "$(SolutionDir)"

Python.Test:
copy "$(TargetPath)" "$(SolutionDir)"
copy "$(TargetDir)*.pdb" "$(SolutionDir)"

Speaking of runtests.py, it still doesn't run to completion.  I'll be working on
the Int64 issue shortly.

Barton
Windows 7
Python 2.6

_________________________________________________
Python.NET mailing list - [hidden email]
http://mail.python.org/mailman/listinfo/pythondotnet
Reply | Threaded
Open this post in threaded view
|

This assembly is built by a runtime newer than the currently loaded runtime

Dave Hirschfeld
In reply to this post by Brandon Craig Rhodes
I needed to access .NET dlls compiled for .NET4 and also ran into the
System.BadImageFormatException error.

I opened PythonDotNET in VS2010 and it compiled fine with only a couple of
errors about System.Security.Permissions.SecurityAction.RequestMinimum being
obsolete. Unfortunately when I tried to import clr I got the following error:

SystemError: dynamic module not initialized properly

Looking further into it I found that in buildclrmodule.bat lines 33 & 66
referenced the .NET2 idalsm.exe:

%windir%\Microsoft.NET\Framework\v2.0.50727\ilasm /nologo /quiet /dll
%ILASM_EXTRA_ARGS% /include=%INCLUDE_PATH% /output=%OUTPUT_PATH% %INPUT_PATH%

I changed this to reference the .NET4 version:

%windir%\Microsoft.NET\Framework\v4.0.30319\ilasm /nologo /quiet /dll
%ILASM_EXTRA_ARGS% /include=%INCLUDE_PATH% /output=%OUTPUT_PATH% %INPUT_PATH%

...and everything works perfectly!

HTH,
Dave


-----Original Message-----
From: Brandon Craig Rhodes
Sent: 28 May 2010 21:36
To: Dave Hirschfeld
Cc: [hidden email]
Subject: Re: [Python.NET] how can I build an assembly I can AddReference()?

Brandon Craig Rhodes <[hidden email]> writes:

> System.BadImageFormatException: This assembly is built by a runtime newer
> than the currently loaded runtime and cannot be loaded. (Exception from
> HRESULT: 0x8013101B)
>    at System.Reflection.Assembly.nLoadFile(String path, Evidence evidence)
>    at System.Reflection.Assembly.LoadFile(String path)

This afternoon I uninstalled Visual Studio 2010 from my laptop and
re-installed Visual Studio 2008, then rebuilt "Brandon.dll", in the
hopes that 2010 was simply too recent a version of Studio to be using
with the c:\python26 from the python.org page.  Sadly, I was wrong; I
still get the above error when trying to import the DLL.


The information transmitted is the property of Gazprom Marketing & Trading Ltd and is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Statements and opinions expressed in this e-mail may not represent those of the company. Any review, retransmission, dissemination and other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender immediately and delete the material from any computer.

Registered office: Gazprom Marketing & Trading Ltd, Gazprom House, 60 Marina Place, Hampton Wick, Kingston upon Thames, KT1 4BH. Registered in England No. 3768267


_________________________________________________
Python.NET mailing list - [hidden email]
http://mail.python.org/mailman/listinfo/pythondotnet