Accessing .net core dll using python - c#

I need to access a C# dll which is built in .net core (.NETCore version = v1.1). I tried in the below way but I am getting the import error.
import clr
clr.AddReference("dllname") - No error
from dllname import *
Got Import Error exception saying no module named dllname.
Note: I tried in both Iron python and python both are giving me the same exception.

I'm trying on Fedora 29, using mono 5.18, python3.7 and netcore 3.0.100-preview-009812,
and seems to work if you use absolute paths to resolve the netcore dll
import clr
import os
clr.AddReference(os.path.abspath('./bin/Debug/netstandard2.0/sample.dll'))
import sample
p = sample.Person(name='Peter')
netcore project was generated like that
dotnet new classlib -o sample
Person class
using System;
namespace sample
{
public class Person
{
public string Name { get; set; }
}
}
UPDATE
Based on data provided by #SMHP seems like an incompatibility between main .NET framework/mono (pythonnet runtime) and a library targeting .netcoreapp 2.0.

You get import error because you are using dllname in import statement. Instead of using dllname use namespace of the dll.
P.S: don't use same name for dll and namespace it will throw an error while importing in python
import clr
clr.AddReference("dllname") - No error
from namespace import *

Related

Error on SSIS Script Task to load data from MongoDB to SQL Server: Could not load file or assembly MongoDB.Driver.Core

I want to create a Script Task to load data from MongoDB to SQL Server.
I am using Visual Studio 2017 and target SQL Server version is 2017.
The default target .NET Version of the script task based on the above is 4.5, therefore I got the 2.3 version, which was the latest to target 4.5
In order to get the dlls, I first used NuGet to download the packages and then copied the following dlls:
MongoDB.Driver.dll
MongoDB.Driver.Core.dll
MongoDB.Bson.dll
I followed instructions from here:
http://codeingaddiction.blogspot.com/2011/06/how-to-add-strong-name-to-existing-dll_16.html
In order to produce strong named dlls.
Finally, I added the dlls on GAC on the following path
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools
I then created a script task and manually added the 3 dlls.
My test code is the following:
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Core;
using MongoDB.Bson.Serialization;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void PreExecute()
{
base.PreExecute();
}
public override void PostExecute()
{
base.PostExecute();
}
public override void CreateNewOutputRows()
{
MongoClient client = new MongoClient("mongodb://dgm-mongodbdev-01.development.dc.opap:27017");
IMongoDatabase database = client.GetDatabase("sportsbetting-staging");
IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("event");
collection.Find<BsonDocument>(null).Limit(3);
Console.WriteLine(collection);
}
}
Trying to build gives the following error:
Severity Code Description Project File Line Suppression State
Error The type 'IAsyncCursorSource<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'MongoDB.Driver.Core, Version=2.3.0.157, Culture=neutral, PublicKeyToken=null'.
MongoDb Core Driver does not have any additional dependencies that I may have missed. For 4.5 version of .NET the only dependency is MongoDB.Bson which is added as a reference.
The only article I have found for SSIS script task is this:
https://arcanecode.com/2014/01/14/importing-mongodb-data-using-ssis-2012/
Which is obsolete because it used the version 1.x of the driver.
Any ideas? The message seems misleading because it seems clear that I am not missing any dependency.
Finally, my answer was provided on the following post:
How to fix "Referenced assembly does not have a strong name" error?
Apparently,
MongoDB.Driver.Core.dll
MongoDB.Driver.dll
Have reference to
MongoDB.Bson.dll
Therefore, the public key token had to be added on the il files before re-assembling

How to use library which include Xamarin.iOS in Unity?

I created dll which include Xamarin.iOS by Visual Studio 2017.
using JavaScriptCore;
using Foundation;
namespace JSCore
{
public static class MyClass
{
public static int Test()
{
JSContext jsContext = new JSContext();
jsContext[new NSString("arg1")] = JSValue.From(2, jsContext);
jsContext[new NSString("arg2")] = JSValue.From(2, jsContext);
var jsResult = jsContext.EvaluateScript("arg1 + arg2;");
return jsResult.ToInt32();
}
}
}
I want to use this library in Unity.
I put this dll in Unity Plugins folder and write script (call MyClass.Test()).
In Editor, there is no error. But when I build project, some error appeared.
IL2CPP error for method 'System.Void ObjCRuntime.Runtime::set_UseAutoreleasePoolInThreadPool(System.Boolean)' in assembly '/Users/[MyName]/Documents/JavaScriptRuntimeTest/Temp/StagingArea/Data/Managed/Xamarin.iOS.dll'
Additional information: Build a development build for more information. Object reference not set to an instance of an object.
I read error sentence. I think this is the version error about System.dll.
Xamarin.iOS reference System.dll 2.0.5.0.
Unity's API Compatibility Level is .NET Standard 2.0.
How to avoid this error ?
Unity's Mono runtime isn't compatible with Xamarin, so the only possibility to use your library is to remove the IOS part.

Call python script from .Net Core using pythonnet

I'm trying to get pythonnet to work in my .Net Core app running on Linux.
I've made a reference to Python.Runtime.dll (which I got from nuget) in my .Net Core project.
My code is:
using System;
using Python.Runtime;
namespace pythonnet_w
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start");
using (**Py.GIL()**) {
// blabla
}
Console.WriteLine("End");
}
}
}
I get this runtime error:
Unhandled Exception: System.MissingMethodException: Method not found: 'System.Reflection.Emit.AssemblyBuilder
System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess)'.
at Python.Runtime.CodeGenerator..ctor()
at Python.Runtime.DelegateManager..ctor()
at Python.Runtime.PythonEngine.Initialize(IEnumerable`1 args, Boolean setSysArgv)
at Python.Runtime.PythonEngine.Initialize(Boolean setSysArgv)
at Python.Runtime.PythonEngine.Initialize()
at Python.Runtime.Py.GIL()
at pythonnet_w.Program.Main(String[] args) in D:\Development\~.Net libraries (3.part)\phytonnet\.Net Core test (phytonnet)\c#\pythonnet_test\Program.cs:line 10
/usr/sbin/pythonnet_w: line 5: 19487 Aborted dotnet "/usr/share/pythonnet_wit/pythonnet_w.dll"
Tried to find a solution in these threads but without any luck:
How do I run a py file in C#?
Call Python from .NET
UPDATE:
I tried to open \pythonnet-master\src\runtime**Python.Runtime.csproj** in Visual Studio to see if I can compile it to .Net or .Core, but I can only compile to .Net framework.
I found this article "How to port from .net framework to .net standard"
Is that what I have to do?
I finally had success by using a self-compiled Python.Runtime.dll as of version 2.4.0. There are two options to create a working DLL:
Remove the other target framework net461 from the respective project file (leaving only netstandard2.0).
Run dotnet build using the appropriate options
For option 2, the following works(in Windows, Mac and Linux):
Clone the pythonnet repo (https://github.com/pythonnet/pythonnet)
In the pythonnet folder, cd src\runtime
Run dotnet build -c ReleaseWinPY3 -f netstandard2.0 Python.Runtime.15.csproj in Windows(in Mac/Linux, replace ReleaseWinPY3 with ReleaseMonoPY3 because the former use python37 and the later use python3.7)
Set DYLD_LIBRARY_PATH in Mac or LD_LIBRARY_PATH in linux(Windows skip):
export DYLD_LIBRARY_PATH=/Library/Frameworks/Python.framework/Versions/3.7/lib
Use the built DLL bin\netstandard2.0\Python.Runtime.dll as DLL reference in your Visual Studio .NET Core project (mine targets netcoreapp2.2, netcoreapp3.1 is also tested ok), e.g. in conjunction with the following code,
using System;
using Python.Runtime;
namespace Python_CSharp
{
class Program
{
static void Main(string[] args)
{
using (Py.GIL())
{
dynamic os = Py.Import("os");
dynamic dir = os.listdir();
Console.WriteLine(dir);
foreach (var d in dir)
{
Console.WriteLine(d);
}
}
}
}
}
You can host the IronPython interpreter right in your .NET application. For example, using NuGet, you can download the right package and then embed the script execution (actually the IronPython engine) right into your application.
Ref:
https://medium.com/better-programming/running-python-script-from-c-and-working-with-the-results-843e68d230e5

Import issue with IronPython and Visual Studio 2015

I want to integrate IronPython in my .NET C# Library but I have always the following exception
Additional information: No module named 'modulename'
In my C# library project, I've installed the following IronPython NuGet
Install-Package IronPython
Install-Package IronPython.StdLib
Python simple code (getLogScaledPNG.py):
import numpy as np
import matplotlib.pyplot as plt
def getLogScaledPNG(filename):
data = plt.imread(filename);
data[data == 0.] = np.nan;
logdata = np.log(data);
plt.imsave("logimage.png", logdata, cmap="gray");
print 'Scaled Image Saved'
C# code:
using IronPython.Hosting;
var ipy = Python.CreateRuntime();
dynamic getLogScaledPNG = ipy.UseFile(#".\PythonScripts\getLogScaledPNG.py");
getLogScaledPNG.getLogScaledPNG("toto.png");
When I execute this C# code, I've got the following Exception:
Additional information: No module named numpy
I don't understand where and how can I add this module ?
I just have the reference to the IronPython DLLs in my .NET project and I haven't got any folders where I can add this module
In addition to the IronPython DLLs, you need Python standard library scripts.
Download IronPython.StdLib.2.7.8.zip, extract everything to a folder
And add this to your code:
ScriptEngine engine = Python.CreateEngine();
var searchPaths = engine.GetSearchPaths();
searchPaths.Add(#"C:\yourLibFolder");
engine.SetSearchPaths(searchPaths);

PHP DOTNET hell

I'm quite a newbie in PHP and today I discovered DOTNET class.
So I studied manual, surfed the web to find some example and finally wrote my test app:
Created a new DLL using Framework 4.0 Client Profile
Signed the assembly with a strong name key
Marked assembly as COM-Visible
This is the test code I wrote
using System;
namespace CSharpCOM
{
public class CSharpCOMClass
{
public string Base64(string s)
{
return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(s));
}
}
}
I compiled the assembly and then registered in GAC (gacutil /if fullpath\CSharpCOM.dll).
If I use gacutil /l CSharpCOM I see
La cache di assembly globale contiene gli assembly seguenti:
csharpcom, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=beb607ae770f5750, processorArchitecture=MSIL
Numero di elementi = 1
So everything seems ok.
Then wrote this basic php:
<?php
try{
$csclass = new DOTNET("CSharpCOM, Version=1.0.0.0, Culture=neutral, " .
"PublicKeyToken=beb607ae770f5750",
"CSharpCOM.CSharpCOMClass");
echo $csclass->Base64("Test string"),"\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
?>
Whatever I try, loading page hosted in Apache (http://localhost/test01/dotnet.php) I always get
Caught exception: Failed to instantiate .Net object [CreateInstance]
[0x80070002] Impossibile trovare il file specificato.
Translation could be: unable to find specified file
Just another thing: using some example (a very basic one here) I read that my assembly (when registered) should be found on %windir%\assembly, but I'm only able to find it in %windi%\Microsoft.NET\assembly\GAC_MSIL\CSharpCOM\v4.0_1.0.0.0__beb607ae770f5750: is this correct? Why don't I have it on first directory?
More: if I create another framework project and try to add a .NET reference I can't find my assembly: is this related to the fact I'm not able to load this assembly from PHP?
Last note: I tried it on Windows XP Professional SP3 32bit and on Windows Seven Enterprise 64bit
UPDATE:
This works:
$form = new DOTNET('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form');
but this one does not:
$form = new DOTNET('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form');`
Is it possible that PHP can load only framework 2.0 assemblies?
According to this bug report the DOTNET class is not loading .NET 4.0 DLLs. If you're not using any of the new libraries in .NET 4.0 you can target your to .NET 3.5 or lower by opening the project properties and on the "Application" tab change the "Target framework" to ".NET Framework 3.5 Client Profile"
Now when you install your DLL into the GAC it will get installed into the CLR 2.0 GAC and should be able to be loaded using the DOTNET class in PHP.
There is a library out there called NetPhp (https://github.com/david-garcia-garcia/netphp) that will let you:
Use any .Net binaries (even without COM Visibility) and ANY version of the .Net framework including CLR4
Dump a PHP class model
Iterate over .Net collections directly from PHP
PHP class model generation, to use PHP classes as if it where .Net
Automatic propagation of .Net errors into native PHP exceptions that can be properly handled
Acces native enums and static methods
Use class constructors with parameters
Debug .Net and PHP code at the same time as if it was a single application.
There is a project with code samples here:
https://github.com/david-garcia-garcia/netphp-sample
This is what a piece of code with NetPhp looks like:
$datetime = $runtime->TypeFromName("System.DateTime");
$datetime->Instantiate();
echo $datetime->ToShortDateString()->Val(); // Outputs 01/01/0001
// We can only use Int32 from native PHP, so parse
// an Int64 that is equivalent to (long) in the DateTime constructor.
$ticks = $runtime->TypeFromName("System.Int64")->Parse('98566569856565656');
$ticks = \ms\System\netInt64::_Parse('98566569856565656');
$datetime->Instantiate($ticks);
echo $datetime->ToShortDateString()->Val(); // Outputs 07/05/0313
$now = $runtime->TypeFromName("System.DateTime")->Now;
echo $now->ToShortDateString()->Val(); // Outputs "23/10/2015"
$now = $runtime->TypeFromName("System.DateTime")->Now();
echo $now->ToShortDateString()->Val(); // Outputs "23/10/2015"
$timer = $runtime->TypeFromName("System.Timers.Timer")->Instantiate();
$timer->AutoReset(TRUE);
$timer->AutoReset = TRUE;

Categories

Resources