ERLEDIGT
NEIN
NEIN
ANTWORTEN
6
6
ZUGRIFFE
992
992
EMPFEHLEN
-
Hallo,
ich möchte eine Instanz in PHP von einer DLL erstellen, welche in C# geschrieben wurde und mit dem .Net Framework 4.0 kompiliert wurde. PHP findet allerdings die zu ladende dll, welche sich im globalen Assembly Cache (neuerdings unter dem Microsoft.Net Verzeichnis) befindet, nicht:
Ich vermute, dass PHP nur in dem globalen Assembly Cache unter dem "Windows\assembly" Verzeichnis nach der DLL schaut, nicht aber unter dem neuen Verzeichnis. Diese Vermutung hat sich bei mir verstärkt, da das Erstellen einer Instanz funktioniert hatte, sofern die DLL im globalen Assembly Cache unter Windows registriert war. Hat jemand eine Idee ob die DOTNET Klasse von PHP auch bei Assemblies, welche mit .Net Framework 4.0 kompiliert wurden, verwendet werden können? Oder gibt es eine Möglichkeit die .Net 4.0 DLL mittels gacutil 4.0 in den alten globalen assembly cache zu registrieren? Mein Aufruf sieht folgendermaßen aus:Failed to instantiate .Net object [CreateInstance] [0x80070002] Das System kann die angegebene Datei nicht finden.
Zur Erinnerung: Der Aufruf funktioniert bei Assemblies, die im alten globalen Assembly Cache installiert sind (windows\assembly). Die Abhängigkeiten der DLL wurden auch alle gefunden (überprüft mit dem Dependency Walker). Außerdem würde das Fehlen einer Abhängigkeit explizit in der Fehlermeldung erscheinen.PHP-Code:$lFullAssemblyName = "Assembly Name, Version=x.x.x.x, Culture=neutral, ".
"PublicKeyToken=xxxxxxxxxxxxxxxx, processorArchitecture=MSIL";
$lFullClassName = "Namespace.Classname";
try
{
$lDotNet = new DOTNET($lFullAssemblyName, $lFullClassName);
}
catch(Exception $lEx)
{
die("Error occurred:<br>".$lEx->getMessage());
}
Gruß, JeyBGeändert von JeyB (02.12.10 um 17:25 Uhr)
-
02.12.10 17:28 #2
Soweit ich das einsehen kann, ruft die Klasse grundsätzlich nur DLLs aus dem GAC auf...
QuelleI can't explain the whole process as I'm not even sure. But as far as I know, in order to get PHP's DOTNET() to work with it, the dll must be registered in the GAC (see: en.wikipedia.org/wiki/Global_Assembly_Cache). Before that though, within the dll, you must jump through the required hoops to get your dll classes and methods to be COM visible (see: msdn.microsoft.com/en-us/library/zsfww439.aspx). Since you have the source, you can clean it up, set it up for COM usage, recompile, then register in the GAC where DOTNET() can find and use it.KIDS Kinderbetreuungsdienst
Xing
"When you play the game of thrones, you win or you die. There is no middle ground."
by Cersei Lannister in "A Game Of Thrones"
-
Das habe ich auch befürchtet. Gibt es aber keine andere Möglichkeit die .Net 4.0 DLL aus der PHP DotNet Klasse heraus zu verwenden oder diese in den alten GAC zu registrieren?
Vielen Dank für jede weitere Antwort.
Gruß, JeyB
-
03.12.10 10:46 #4
Ich habe den Beitrag mal ins .NET Forum verschoben, weil ich vermute dass hier die Leute mit mehr Ahnung sitzen und nicht den PHP Bereich checken
KIDS Kinderbetreuungsdienst
Xing
"When you play the game of thrones, you win or you die. There is no middle ground."
by Cersei Lannister in "A Game Of Thrones"
-
Also ich habe Änderungen in der com_dotnet.c Datei vorgenommen.
Statt die Assembly direkt vom GAC zu laden (mittels CreateInstance) habe ich die Funktion CreateInstanceFrom verwendet. Danach habe ich PHP 5.3.3 nts (not thread safe) kompiliert und getestet. Ich kann jetzt direkt statt den vollständigen Assemblynamen, den Pfad der DLL angeben und es wird eine Instanz der angegebenen Klasse erstellt. Mein Aufruf sieht jetzt folgendermaßen aus:
Nachteile:PHP-Code:$lAssemblyPath = "C:\\bin\\Assembly.dll";
$lFullClassName = "Namespace.Classname";
try
{
$lDotNet = new DOTNET($lAssemblyPath, $lFullClassName);
}
catch(Exception $lEx)
{
die("Error occurred:<br>".$lEx->getMessage());
}
-Es dauert etwas länger bis die Assembly geladen wurde (laden aus dem GAC ist schneller)
-Ich kann nur eine Instanz von einer Assembly Klasse, welche mit .Net Framework < 4.0 kompiliert wurde, erzeugen.
Der Fehler, dass er die Assembly nicht findet, erscheint nicht mehr, dafür aber dieser Fehler:
Anscheinend kann ich keine Instanz einer Klasse erzeugen, die mit .Net 4.0 kompiliert wurde.Failed to instantiate .Net object [CreateInstance] [0x8013101b]
Hat noch jemand eine Idee? Lasst euch nicht von dem [CreateInstance] verwirren. Das steht nur da drin, weil dieser Wert zuvor in einer Variablen gespeichert wurde. Ich verwende also wirklich die Funktion CreateInstanceFrom.
Gruß, JeyBGeändert von JeyB (03.12.10 um 13:24 Uhr)
-
Habe noch nie was mit PHP gemacht. Den einzigen Satz, den ich verstehe, ist der über die COM-Sichtbarkeit. Besitzt du den Quellcode der Assembly bzw. wurde sie als COM-Sichtbar kompiliert? Das ist in VisualStudio nämlich standardmäßig deaktiviert.
-
Habe die Assembly COM-Sichtbar kompiliert. Es funktioniert ja, sofern ich für die Assembly .Net Framework < 4.0 verwende. Habe nun in der com_dotnet.c Datei gesehen, das die Schnittstelle von System.AppDomain für die Instanziierung einer .Net Klasse verwendet wird. Zum laden wird die GUID angegeben. Mittels oleview konnte ich die GUID der Schnittstelle, welche in der mscorlib.dll definiert ist, herausfinden und habe diese GUID von .Net 2.0 durch die von .Net 4.0 ersetzt.
Nun erhalte ich folgenden Fehler:PHP-Code:// .Net 2.0 GUID der Schnittstelle System.AppDomain
//const GUID IID_mscorlib_System_AppDomain = {
//0x05F696DC, 0x2B29, 0x3663, {0xAD, 0x8B, 0xC4, 0x38, 0x9C, 0xF2, 0xA7, 0x13 }};
// .Net 4.0 GUID der Schnittstelle System.AppDomain
const GUID IID_mscorlib_System_AppDomain = {
0x5FE0A145, 0xA82B, 0x3D96, {0x94, 0xE3, 0xFD, 0x21, 0x4C, 0x9D, 0x6E, 0xB9 }};
D.h. er scheitert beim Aufruf der Funktion "IUnknown_QueryInterface".Failed to init .Net runtime [QI: System._AppDomain] Schnittstelle nicht unterstützt
Im Anhang befindet sich die vollständige com_dotnet.c Datei.PHP-Code:static HRESULT dotnet_init(char **p_where TSRMLS_DC)
{
HRESULT hr;
struct dotnet_runtime_stuff *stuff;
IUnknown *unk = NULL;
char *where = "";
stuff = malloc(sizeof(*stuff));
memset(stuff, 0, sizeof(*stuff));
where = "CoCreateInstance";
hr = CoCreateInstance(&CLSID_CorRuntimeHost, NULL, CLSCTX_ALL,
&IID_ICorRuntimeHost, (LPVOID*)&stuff->dotnet_host);
if (FAILED(hr))
goto out;
/* fire up the host and get the domain object */
where = "ICorRuntimeHost_Start\n";
hr = ICorRuntimeHost_Start(stuff->dotnet_host);
if (FAILED(hr))
goto out;
where = "ICorRuntimeHost_GetDefaultDomain";
hr = ICorRuntimeHost_GetDefaultDomain(stuff->dotnet_host, &unk);
if (FAILED(hr))
goto out;
where = "QI: System._AppDomain";
// Dieser Aufruf verläuft nicht positiv
hr = IUnknown_QueryInterface(unk, &IID_mscorlib_System_AppDomain, (LPVOID*)&stuff->dotnet_domain);
if (FAILED(hr))
goto out;
COMG(dotnet_runtime_stuff) = stuff;
out:
if (unk) {
IUnknown_Release(unk);
}
if (COMG(dotnet_runtime_stuff) == NULL) {
/* clean up */
if (stuff->dotnet_domain) {
IUnknown_Release(stuff->dotnet_domain);
}
if (stuff->dotnet_host) {
ICorRuntimeHost_Stop(stuff->dotnet_host);
ICorRuntimeHost_Release(stuff->dotnet_host);
}
free(stuff);
*p_where = where;
return hr;
}
return S_OK;
}
Habe auch nachgeschaut ob in anderen Dateien eine Verwendung einer .Net 2.0 Assembly gemacht wird , konnte aber dies bezüglich nichts finden. Hat sonst noch jemand eine Idee? Bin für jede weitere Antwort dankbar.
Gruß, JeyB
Ähnliche Themen
-
DotNet in PHP
Von JeyB im Forum PHPAntworten: 26Letzter Beitrag: 16.12.10, 19:32 -
Windows Messages in DOTNet
Von MarioR im Forum .NET Windows FormsAntworten: 0Letzter Beitrag: 29.09.09, 10:32 -
dotNet und Soap Problem
Von The Nephilim im Forum .NET Web und KommunikationAntworten: 0Letzter Beitrag: 23.10.06, 16:28 -
.net 1.x Framework wird installiert trotz .net 2.0 Framework
Von BWilhelm im Forum .NET CaféAntworten: 5Letzter Beitrag: 12.06.06, 07:28 -
myodbc & dotNET Performance-/Stabilitätsprobleme
Von C-H im Forum Relationale DatenbanksystemeAntworten: 1Letzter Beitrag: 10.06.05, 11:36





Zitieren

Login





