Seite 1 von 1
call c# dll functions from python 2.5
Verfasst: Donnerstag 3. Februar 2011, 08:17
von Theo
Hi,
der Simulator den ich nutze hat ein Python upgrade erfahren, von Version 2.2 auf 2.5 ( ja ich weiss total aktuell ... )
Nun gibt es folgendes Problem.
Ich habe bestimmte Komponenten, die auf Funktionen einer C# dll zugreifen. Das hab ich damals mit calldll gemacht, war alles bissl umstaendlich, aber es ging am Ende.
Nun mit der Version 2.5 gibt es das calldll modul leider nicht mehr. Ich hab gestern ewig im Netz gesucht, ob es etwas equivalentes mit 2.5 gibt. Ich bin immer nur auf ctypes gestossen, aber soweit ich weiss funktioniert das nur mit c/c++ - Dlls
Ok nun die Frage an euch, gibt es mit Version 2.5 irgendwie die Möglichkeit Funktionen einer C# Dll von Python aus aufzurufen?!
Vielen Dank schonmal,
Theo
Re: call c# dll functions from python 2.5
Verfasst: Donnerstag 3. Februar 2011, 08:49
von cofi
Ist IronPython denn eine Option? Da Python dann direkt auch der CLR laeuft sollte das kein Problem sein.
Zu ctypes kann ich da leider nichts sagen.
Re: call c# dll functions from python 2.5
Verfasst: Donnerstag 3. Februar 2011, 08:59
von Theo
cofi hat geschrieben:Ist IronPython denn eine Option? Da Python dann direkt auch der CLR laeuft sollte das kein Problem sein.
Nope ist leider keine Option, da die Skriptsprache fest im Simulator enthalten ist, also am klassichen Python komm ich leider nicht drumherrum
Re: call c# dll functions from python 2.5
Verfasst: Donnerstag 3. Februar 2011, 13:19
von Leonidas
Was denn für ein ``calldll``-Modul? Ich denke nicht dass so ein Modul Teil von Python 2.2 war und inzwischen entfernt wurde.
Re: call c# dll functions from python 2.5
Verfasst: Donnerstag 3. Februar 2011, 13:30
von Theo
Leonidas hat geschrieben:Was denn für ein ``calldll``-Modul? Ich denke nicht dass so ein Modul Teil von Python 2.2 war und inzwischen entfernt wurde.
Ui ka, von welcher Version das war. Wo ich damals wegen dem gleichen Problem gesucht habe, bin ich auf eine Seite gestossen wo das beschrieben war und da gabs die 'calldll.pyd' zum herunterladen
Re: call c# dll functions from python 2.5
Verfasst: Donnerstag 3. Februar 2011, 14:16
von BlackJack
@Theo: Das klingt eigentlich nach Sam Rushings `calldll`; Teil von DynWin:
http://www.nightmare.com/~rushing/dynwin/
Allerdings sieht das nach einem Modul aus, mit dem man "native" DLLs ansprechen kann. .NET-DLLs enthalten ja AFAIK keinen Maschinencode den man "normal" aufrufen kann. Da Rushing als Ersatz `ctypes` aus der Standardbibliothek empfiehlt, kann es ja irgendwie nicht das gewesen sein, was Du verwendet hast!?
Re: call c# dll functions from python 2.5
Verfasst: Donnerstag 3. Februar 2011, 15:17
von Theo
Ok hier mal ein kleiner Auszug aus dem Script
Code: Alles auswählen
from vcScript import *
import calldll
import struct
def GetMemAlloc( size, format, value ):
refMem = calldll.membuf( size )
string_packed = struct.pack( format, value )
refMem.write( string_packed )
return refMem
def CreateMemInt( value ):
return GetMemAlloc( 4, "i", value )
def CreateMemDouble( value ):
return GetMemAlloc( 8, "d", value )
def CreateMemString( value ):
length = len( value ) + 1
return GetMemAlloc( length, str(length) + "c", value )
def ReadMemInt( refValue ):
return struct.unpack("i", refValue.read())[0]
def ReadMemDouble( refValue ):
return struct.unpack("d", refValue.read())[0]
def ReadMemString( refValue ):
return calldll.read_string( refValue.address() )
def LoadDLL( dll_name ):
global dll_handle
dll_handle = calldll.load_library( dll_name )
def LoadMethod( method_name ):
global dll_handle
if dll_handle != 0:
return calldll.get_proc_address(dll_handle, method_name )
else:
return 0;
def AddExternal( A, B ):
handle_method = LoadMethod( "Add" )
refA = CreateMemInt( A )
refB = CreateMemInt( B )
refResult = CreateMemInt( -1 )
calldll.call_foreign_function( handle_method, 'lll', '', (refA.address(), refB.address(), refResult.address()) )
Result = ReadMemInt( refResult )
return Result
...
...
def StartSpeedSimulation():
handle_method = LoadMethod( "StartSimulationAtFullSpeed" )
refErrorCode = CreateMemInt( -1 )
calldll.call_foreign_function( handle_method, 'l', '', (refErrorCode.address(),) )
print "error code : " + str( ReadMemInt(refErrorCode) )
def StopSpeedSimulation():
handle_method = LoadMethod( "StopSimulation" )
refErrorCode = CreateMemInt( -1 )
calldll.call_foreign_function( handle_method, 'l', '', (refErrorCode.address(),) )
print "error code : " + str( ReadMemInt(refErrorCode) )
...
...
def OnRun():
global dll_handle
print "enter onrun"
# get access
LoadDLL( 'SpeedSimulatorWrapper.dll' )
# trivial tests
print "trival interface tests:"
print AddExternal( 5, 6 )
...
...
calldll.free_library(dll_handle)
print "exit onrun"
Also fuer mich war das damals ein enormes gebastle. Leider funktioniert diese 'calldll.pyd' mit der Python-Version 2.5 des Simulators nicht mehr.
Ich hab jetzt schon probiert den Umweg mittels ctypes zu gehen: Python <-> C++/CLI-DLL <-> C#-DLL
Funktioniert leider nicht, da bekomm ich den Fehler: ' WindowsError: exception code 0xe0434f4d'
Das 'C++/CLI-DLL <-> C#-DLL' funktioniert auch problem los, hab dies getestet in dem ich den Python-Teil durch eine C++ (Konsolenanwendung) <-> C++/CLI-DLL <-> C#-DLL ersetzt habe
Irgendwie ist da der Wurm drin :'(
Re: call c# dll functions from python 2.5
Verfasst: Freitag 4. Februar 2011, 00:25
von Leonidas
Naja, du müsstest schon den ``ctypes``-Code zeigen, damit man da irgendwas dazu sagen kann…
Re: call c# dll functions from python 2.5
Verfasst: Freitag 4. Februar 2011, 10:14
von Theo
Code: Alles auswählen
from vcScript import *
from ctypes import *
def ButtonTestDll_click( prop ):
x = CDLL( _sPathToDll.Value.split( "file:///" )[1] ) #path to 'PythonAndCPlusPlus.dll'
print x
f = c_int(5)
print f
print str( x.fakultaet( f ) )
_comp = getComponent()
_sPathToDll = _comp.getProperty( "PathToDll" )
_buttonTestDll = _comp.getProperty( "TestDll" )
_buttonTestDll.OnChanged = ButtonTestDll_click
Und das kommt dann als Fehlermeldung am Ende raus
<CDLL 'D:\SVN_VC\projects\_Dualis\C_Sharp_Projects\PythonAndCPlusPlus\Debug\PythonAndCPlusPlus.dll', handle 650a0000 at 17102ff0>
c_long(5)
Error at "Name::PythonSkript":
Traceback (most recent call last):
File "Name::PythonSkript", line 12, in ButtonTestDll_click
WindowsError: exception code 0xe0434f4d
PythonAndCPlusPlus.cpp
Code: Alles auswählen
#include "stdafx.h"
#include "PythonAndCPlusPlus.h"
using namespace PythonAndCSharp;
#using <D:\SVN_VC\projects\_XXX\C_Sharp_Projects\PythonAndCSharp\PythonAndCSharp\bin\Debug\PythonAndCSharp.dll>
// Berechnet die Fakultaet einer ganzen Zahl
int fakultaet(int n)
{
return PythonAndCSharp::Class1::fakultaet(n);
}
PythonAndCPlusPlus.h
Code: Alles auswählen
#pragma once
using namespace System;
// Berechnet die Fakultaet einer ganzen Zahl
extern "C" __declspec(dllexport) int __cdecl fakultaet(int n);
PythonAndCSharp.cs
Code: Alles auswählen
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
namespace PythonAndCSharp
{
public class Class1
{
public static int fakultaet(int n)
{
int i;
int ret = 1;
for (i = 1; i <= n; i++)
{
ret *= i;
}
return ret;
}
}
}
Re: call c# dll functions from python 2.5
Verfasst: Samstag 5. Februar 2011, 00:20
von jerch
C++ funktioniert hier, da es sowohl im managed als auch unmanaged Modus laufen kann. Probier mal, den C++-Teil mit einem
#pragma unmanaged bei gesetztem
/clr Flags zu versehen.
Weitere Infos hierzu:
-
http://msdn.microsoft.com/en-us/library/ms973872.aspx
-
http://msdn.microsoft.com/en-us/library/ms173266.aspx
Alternativ kannst Du den C#-Code auch als COM-Objekt anlegen und darüber zugreifen. Das zumindest ist der von MS empfohlene Weg. Die native Anbindung über eine Flat-API mit C++-Wrapper ist für komplexere Parameterübergabe oder Rückgabe fehlerträchtig.