I'm using CPython and I have a C# dll. I'm trying to use Python for .NET to make them talk. I can't use IronPython because I need to integrate this into an existing CPython system.
I'm completely new to Python for .NET, and I actually have very little experience with Python and no experience with C#. So please forgive me if my question seems very basic.
I'm using Python 2.7.3, and I downloaded
pythonnet-2.0-alpha2-clr2.0_131_py27_UCS2 and unzipped it into a folder named pyfornet_test, which also contains the dll I'm trying to use (called DotNet4Class.dll)
Then I run this:
import sys
import os
import clr
sys.path.append(r"C:\pyfornet_test")
clr.AddReference("DotNet4Class.dll")
Which gives me this error:
System.IO.FileNotFoundException: Unable to find assembly 'DotNet4Class.dll'.
at Python.Runtime.CLRModule.AddReference(String name) in C:\Users\Barton\Documents\Visual Studio 2008\Projects\PyShar
p\trunk\pythonnet\src\runtime\moduleobject.cs:line 375
Any advice would be much appreciated. Thank you!
One reason can be Windows was not enabling it to load from "external sources". To fix this:
Right-click on the .dll
"Properties"
Under "General", click "Unblock"
Try this (without extension .dll):
clr.AddReference(r"C:\pyfornet_test\DotNet4Class")
Is DotNet4Class.dll built against .NET 4? I assume so based on the naming of the dll.
Note the issue here: http://sourceforge.net/tracker/?func=detail&aid=3293169&group_id=162464&atid=823891
clr.AddReference fails when assembly is built with .NET 4.0 - ID: 3293169
I'd read the solution, but essentially, you need to rebuild and recompile the python for .NET project under .NET 4.
I'll also mention that projects like this, that aren't actively developed and used by lots of people, generally have subtle idiosyncrasies that make knowledge of the platform essential to work around problems such as this. It sounds like you're trying to hack this solution in without understanding much about python or .NET which is always going to be fraught with problems.
Did you try clr.FindAssembly?
import clr
import sys
assemblydir = r"C:\pyfornet_test"
assemblypath = r"C:\pyfornet_test\DotNet4Class.dll"
sys.path.append(assemblydir)
clr.FindAssembly(assemblypath)
I don't know why it works, but this code works on my computer (Python 2.7, .NET4)
I have code like this (I copied MyRightClickMenuService.dll to the same directory as my script.py). It is built against .Net 4.0.
# script.py
import clr
import os
import sys
sys.path.append(os.path.dirname(__file__))
clr.AddReference('MyRightClickMenuService')
clr.AddReference('System')
clr.AddReference('System.Security')
from MyRightClickMenuService import (
AclSecuredNamedPipeBinding,
MyMenuItem,
MyContextMenuService,
etc
)
Checklist
The folder(s) containing the DLL(s) is/are added to sys.path before loading. You may append, or sys.path.insert(0, dll_folder) to put it first on the list.
You call clr.AddReference('my_dll') without the dll extension (for my_dll.dll), after adding the folder to sys.path
The DLL Target Architecture is the same as the CPython version bitness. That is, if Architecture is x64, use 64-bit python, and if Architecture is x86, use 32-bit python. (instructions for this below)
How to check target Architecture for DLL?
I Used ILSpy (free and open source) -> Open DLL -> Check the output. Below example output.
What worked for me was to Unblock the dll file.
if u download the dll file or took it from different computer it might be blocked. So unblocked solved the issue for me.
To unblock right click on the properties if the dll file and check the Unblock box at the bottom
Related
I'm using Python.NET to create wrapper for iText.net (https://github.com/itext/itext7-dotnet).
The dll is named itext.kernel.dll and the python script is in the samne folder of all the itext dlls.
With Jetbrain dotPeek I see that itext.kernel has various namespaces; the namespace iText.Kernel.Pdf is what I need, in particular the public class PdfReader.
Here's what I'm doing (from the docs on https://pythonnet.github.io/):
import clr
clr.AddReference('itext.kernel')
sys.path.append(os.getcwd()) # the script is currently in the dll folder
from iText.Kernel.Pdf import PdfReader
But this gets me a "ModuleNotFoundError: No module named 'iText'" error.
I can't understand what it's wrong, can someone point me to the right direction? Thanks.
edit: I can import and use iTextSharp just fine, it seems iText7 has something different.
Well, long story short I really wanted this to work... and solved my issue!
I tried using older builds, and I found out that build 7.0.8 worked fine.
I compared it with build 7.1.11 (the one I was having problems with) using dotPeek, and noticed it has some references, namely BouncyCastle.Crypto, Common.Logging and Common.Logging.Core.
I did put them in the project folder, but still no dice... until I noticed I was using BouncyCastle.Crypto build 1.8.6, while the itext.kernel referred build 1.8.5! Replacing with that version solved the issue.
Basically the newer builds of iText7 have 3 referenced libs, that must be present in the exact same version (at least to be imoported by pythonnet).
I hope this can help someone that has issues similar to mine.
How do I import and use an .SO file that I extracted from apk file?
I've used ctypes library in Linux but it gave me error on every way I tried it.
There are 2 version of the .so files: arm64, and armeabi.
When i tried import the armeabi version, which is 32-bit, it gave me
wrong ELF class: ELFCLASS32
and so I try the arm64, and somehow I got
cannot open shared object file: No such file or directory
I can assure you it is not a typo path, I tried to copy it using the same path. but I cannot import it because no such file.
code:
import ctypes
def main():
TestLib = ctypes.CDLL('/home/manalkaff/Desktop/arm64-v8a/nativelibrary.so')
if __name__ == '__main__':
main()
Is this how I am supposed to do it? Or there is another way?
You can try to decompile and port your shared object to x86. To do this you should load your binary in Ghidra and extract all the functions except utility ones like JNI initialization etc. which will be inserted by compiler automatically if required. Then rebuild using compiler and IDE of your choice like Clion + Clang. Not forget to fix some errors and switch to Windows API if Android API was used. This will require some time and effort though, depending on amount of functions and size of binary (except support stuff once again).
You can't load and execute ARM code on x86 CPU. You need a virtual machine that will emulate ARM CPU for that.
Even after loading the .so file on Linux ARM, you might still be missing some Android dependencies. Use ldd copied.so to see which.
I am trying to learn how to do some scripting to run Grass externally with Python but I can't seem to even find the basic modules called for this type of script. All of the documentation I have seen describes using grass.scripts module but I don't know where to download this. I also saw some information on grass.pygrass but I can't find this either.
I thought that maybe it was builtin to a newer version of Grass so I just downloaded 7.0.0 beta2 and I still find grass.scripts files. Is this a python module like others (matploblib, numpy, scipy etc.) or is it internal to Grass? Sorry for the remedial questions but I am lost here.
I ran the following script (taken from http://grasswiki.osgeo.org/wiki/GRASS_and_Python with quotations added since I run Python 2.7)
GISBASE= 'C:\GRASS-64'
GISRC= 'C:\Documents and Settings\user\.grassrc6'
LD_LIBRARY_PATH= 'C:\GRASS-64\lib'
PATH= 'C:\GRASS-64\etc;C:\GRASS-64\etc\python;C:\GRASS-64\lib;C:\GRASS-64\bin;C:\GRASS-64\extralib;C:\GRASS-64\msys\bin;C:\Python26;'
PYTHONLIB= 'C:\Python26'
PYTHONPATH= 'C:\GRASS-64\etc\python'
GRASS_SH= 'C:\GRASS-64\msys\bin\sh.exe'
and it is fine (though I don't know what it does) but when I add
from grass.pygrass.modules import Module
it returns
ImportError: No module named gras.pygrass.modules
Normally I would download and install the module and the problem would be fixed but I can't find it anywhere.
I ran the following script (taken from http://grasswiki.osgeo.org/wiki/GRASS_and_Python with quotations added since I run Python 2.7)
GISBASE= 'C:\GRASS-64'
GISRC= 'C:\Documents and Settings\user\.grassrc6'
LD_LIBRARY_PATH= 'C:\GRASS-64\lib'
PATH= 'C:\GRASS-64\etc;C:\GRASS-64\etc\python;C:\GRASS-64\lib;C:\GRASS-64\bin;C:\GRASS-64\extralib;C:\GRASS-64\msys\bin;C:\Python26;'
PYTHONLIB= 'C:\Python26'
PYTHONPATH= 'C:\GRASS-64\etc\python'
I don't know why you think Python 2.7 requires you to add quotes. It doesn't.
But it does require you to replace all those Python26 with Python27. And that could easily be your problem. You don't have anything at C:\Python26.
And if you installed Grass somewhere other than C:\GRASS-64 you obviously need to change that as well. (From elsewhere in the file, I get the feeling that 64 refers to version 6.4, not to being 64-bits or something else, and you've downloaded 7.0.0, so I suspect it got installed to something like C:\GRASS-70.)
Or it could be this:
ImportError: No module named gras.pygrass.modules
If you import gras.pygrass.modules instead of grass.pygrass.modules, that's obviously not going to work.
Also, are you actually running that script in the same cmd.exe window that you use to start Python? If not, it's not going to help.
Meanwhile:
All of the documentation I have seen describes using grass.scripts module but I don't know where to download this.
The documentation you linked to answers that question, although it may not be obvious to a novice (once you figure this out, you might want to suggest documentation improvements upstream):
The related files are at $GISBASE/etc/python/grass/script/*.py.
On Windows, of course, that's $GISBASE isn't literally right; it's actually %GISBASE%, which is something like C:\GRASS-64, but it's the same thing. The files are already on your system; there is nothing to download. That's the whole point of setting PYTHONPATH to C:\GRASS-64\etc\python.
Is this a python module like others (matploblib, numpy, scipy etc.) or is it internal to Grass?
Well, it's not exactly "internal to Grass", but it's distributed with Grass, rather than as a separate module.
I'm still not sure I understand everything but I seem to be past this hurdle. I used the script from (https://gis.stackexchange.com/questions/89452/problem-with-python-script-to-control-grass-gis-from-outside-how-to-import-gra/90160#90160) and changed all the relevant path information to suite my installation and apparently, now the grass.script module is accessed. Here is my working script
import os
import sys
gisbase = os.environ['GISBASE'] = 'C:\program files\grass gis 6.4.3' #GISBASE needs to point the root of the GRASS installation directory
gisrc = 'C:\grassdata'
gisdbase = 'C:\grassdata'
location = 'newLocation'
mapset = 'TC'
LD_LIBRARY_PATH = 'C:\program files\grass gis 6.4.3\lib'
PATH = 'C:\program files\grass gis 6.4.3\etc';'C:\program files\grass gis 6.4.3\etc\python';'C:\program files\grass gis 6.4.3\lib';'C:\program files\grass gis 6.4.3\bin';'C:\Python27';'C:\program files\grass gis 6.4.3\Python27';'C:\program files\grass gis 6.4.3\msys'
PYTHONLIB = 'C:\Python27'
PYTHONPATH = 'C:\program files\grass gis 6.4.3\etc\python'
GRASS_SH = 'C:\OSGeo4W64\apps\msys\bin\sh.exe'
sys.path.append(os.path.join(os.environ['GISBASE'], 'etc', 'python'))
import grass.script as grass
I have a USB to one-wire adapter on my desk, I would like to automate the use of it. I use it for programming dallaskeys, which are badges that are programmed and read over onewire.
There is a managed DLL that offers an API, I love python so I would like to use this third party managed DLL from "python for .NET" aka pythonnet.
My script looks as follows, and runs without problems:
import os
import clr
from clr import System
oneWireLibrary = clr.FindAssembly("OWdotNET")
System.Reflection.Assembly.LoadFile(os.path.abspath(oneWireLibrary))
BUT, I can not figure out how to use the classes in the library. I have tried clr.OWdotNET
but that gives me an attribute error.
I have tried clr.AddReference("OWdotNET") as well.
Links:
http://files.maxim-ic.com/sia_bu/softdev/owdocs_400beta2/Docs/OW.NET/OW.NET_Primer.html
http://pythonnet.github.io/
I'm answering this from the viewpoint of IronPython, but I believe it is similar in Python for .NET.
The clr.AddReference call can be thought of as similar to adding the .NET assembly path to sys.path, you are telling the runtime about it, but then you still need to import the namespace into the current scope.
import clr
clr.AddReference("OWdotNET")
from com.dalsemi.onewire import OneWireAccessProvider
adapter = OneWireAccessProvider.getDefaultAdapter()
I am using python 2.6.5 on an Ubuntu intalled server.
I need to integrate an API for our applicaion, in that case, i needed to use a DLL given to me by the API provider. Their example of code about api integration is written in Visual Basic... I made a search on google and found some examples of using ctypes , and i try using cdll and pydll, which caused the following error...
OSError: /home//some.dll: invalid ELF header
One possibility is using IronPython, but i do not have much information about ironpython so i am not sure if it will handle my needs completely..
Is there any available module that let me use that dll on python (or aynthing that i am missing from the exixting ones). It is hard to upgrade my python version?
DLLs may be windows creatures, but if a DLL is 'pure .NET' and doesn't utilize executables specific to windows etc., then it can work often in Linux, through Mono. (mono ipy.exe).
Ironpython's System and similiar windows modules are customized to be os agnostic (to a untested degree).
I have successfully run NHibernate, FluentNHibernate, log4net, and a few other commonly used DLLS in Ubuntu.
import clr
import sys
sys.path.append(os.path.abspath('./DLL')) #where your dlls are
clr.AddReference('System')
clr.AddReference('FluentNHibernate')
from FluentNHibernate.Cfg.Db import PostgreSQLConfiguration
The key seems to be to import DLLs in this fashion. If a dll imports another (fluentnhibernate imports nhibernate), you don't need to import Nhibernate for example.
DLLs are Windows creatures. The only way you'll be able to use a DLL is by using a Windows build of Python. You'll be able to run Windows Python on Ubuntu by having Windows installed inside a virtual machine. You also might be able to run it using Wine.
An alternative, of course, is to ask your API provider if they have a Linux version of the API.
First, check if your DLL is a .NET Assembly file. An "Assembly DLL file" has nothing to do with the assembler. It's simply a way the .NET framework stores its bytecode inside a DLL file!
Do file library.dll in Linux. If it says something like this:
PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows
then you're lucky: it's an assembly file. You can run it on Linux.
Install Mono. Install Python.NET. Forget IronPython: it's dead.
Now, in Python.NET, you can do this:
import clr
clr.AddReference('./library.dll')
# the library has just registered a namespace we can use
from LibraryName import *
but how do you know what to import?
Auto-complete.
Or use monop tool to inspect the DLL like this:
$ monop -r library.dll
Assembly Information:
LibraryName
Version=9.9.3.0
Culture=neutral
PublicKeyToken=null
LibraryName.ClassName
...
$ monop -r library.dll LibraryName.ClassName
public class ClassName {
public ClassName (string inputString);
...
}
and it will tell you everything about that library