DOTNET class nem mukodik minden Assembly-re...

Udv,

Kicsi segitseg kellene PHP ugyben. A DOTNET class segitsegevel szeretnek elerni egy .NET osztalyt, de valamiert nem mukodik. A kod a kovetkezo:
$sp = new DOTNET('System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.IO.Ports.SerialPort');

A kovetkezo hibauzenetet kapom:
Fatal error: Uncaught exception 'com_exception' with message 'Failed to instantiate .Net object [Unwrapped, QI for IDispatch] [0x80004002] No such interface supported '

A furcsa az, hogy egy peldaban latott kod mukodik:
$fm = new DOTNET('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form');

Valaki tudna segiteni, hogy mi lehet a gond vele?

Amit el akarok erni, hogy PHP-bol kezelni tudjam a serial portot. Nezegettem mas ilyen jellegu bovitmenyt php-hez, de egyik sem tudta allitani a BREAK state-t. Jelenleg egy C#-ban irt kis programocskaval kezelem a serial port kimeno bitjeit (Tx, RTS, DTR), es ezt szeretnem atteni PHP ala, hogy bongeszobol tudjam kezelni. Ha lehet elkerulnem azt, hogy exec()-el futassam a C# programot.

Elore is koszonom a segitseget, es barmilyen mas javaslatot szivesen veszek.

Hozzászólások

És ha a C# kódod nyitna egy TCP socketet, a PHP szkript pedig ehhez csatakozna?
Nem túl elegáns, de szerintem megbízhatóan működne.
Esetleg Unix domain socket vagy named pipe?

Fuszenecker_Róbert

Ha nem tudom megoldani csak PHP-bol, akkor lehet inkabb ez lesz, mint exec-el meghivni a C# programot. Ugyis tervben van egy Androidos alkalmazas is, ahonnan iranyitani lehessen, es akkor az is hasznalhatna a TCP socketet...

P.S.Latom kozben szerkesztetted. Ez egy kis hobby dolog, es akinek csinalom Windows-on fogja futtatni.

Sic Transit Gloria Mundi

Esetleg hogyha csinálsz köré egy wrappert, ami implementálja az IDispatchable interfacet?

A hiba alapján a PHP-s cucc COM-ot használ. Olvasd el a doksiját, hogy tényleg így van-e, és mit lehet tenni, ha egy komponens nem tud COM-ot. Megteheted, hogy származtatsz a keretrendszeri osztályból egy sajátot, amit COM-ba regisztrálsz, de az is lehet, hogy nem véletlenül hagyta ki az MS az adott funkciót, mert pl. olyan típusú paramétereket használ, de ennek kicsi az esélye szerintem.

--
joco voltam szevasz

Igen, irnod kene hozza egy IDispatch wrappert, mert a System.Windows.Form-mal ellentetben a SerialPort nem AutoDispatch'd.
Enélkül:

ClassInterfaceType.None: Indicates that no class interface is generated for the class. If no interfaces are implemented explicitly, the class can only provide late-bound access through the IDispatch interface.

míg

ClassInterfaceType.AutoDispatch: Indicates that the class only supports late binding for COM clients. A dispinterface for the class is automatically exposed to COM clients on request. The type library produced by Type Library Exporter (Tlbexp.exe) does not contain type information for the dispinterface in order to prevent clients from caching the DISPIDs of the interface. The dispinterface does not exhibit the versioning problems described in ClassInterfaceAttribute because clients can only late-bind to the interface.
[Kommentből:] COM clients can call the members of this class using the Invoke method from the IDispatch interface.

És mivel a SerialPort-on nincs [ClassInterface] annotáció, így a None a default. (ClassInterface: "Indicates the type of class interface to be generated for a class exposed to COM, if an interface is generated at all.")
S mivel a PHP-s DOTNET az COM-on keresztül matekozik, a szoptálcetlit te nyerted.

Bocs.

vagy maradsz az exec()-nél :)
De én elsőre ezzel próbálkoznék:


using System.IO.Ports;
using System.Runtime.InteropServices;

namespace Valami
{
	[ClassInterface(ClassInterfaceType.AutoDispatch)]
	[ComVisible(true)]
	public class SerialKoszt : SerialPort
	{ }
}

Oszt hajrá, konstruktorokon kívül minden öröklődik.

Ennyi veszodest nem er meg a dolog...

Inkabb azt csinaltam, hogy a C# programocskaba beraktam egy TCP servert. Arra betelnetezve mar tudom remote kezelni a serial portot. Kozben talaltam egy olyat, hogy socket.io, ami elvileg tod socket-et javascriptbol. Igy megsporolom a webservert is...

De azert koszonom a segitseget.

Sic Transit Gloria Mundi

Miert nagyobb ganyolas egy TCP socketre csatlakozni, mint leforditani egy class library-t strongly-named NET assemblieskent, beregisztralni, majd azt php-bol meghivni?

Ami iranyitva van a szerial porton keresztul, az egy lepteto motor, amire egy webcam van teve. A cel, hogy egy helyen lehessen latni a webcam kepet, es 2 gombot, amivel jobbra/balra lehet forgatni a motrot.
Elso otletkent az merult fel, hogy egy webservert feltenni, ami atveszi a streamet, es alatta a 2 gomb. Itt jott volna kepbe a php, de egyetlen serial portos kiegeszito sem tamogatta a BREAK state allithatosagat.
Ezutan kerestem olyasmit, hogyan lehetne dll-t hasznalni php-ben, es esetleg direktben hasznalni a Windows API-t. Keresgeles kozben akadtam ra a DOTNET osztalyra, amivel lehet .NET assemblybol meghivni osztalyokat es metodusokat. Ez is jo lett volna, mert amugy is C#-ban irtam a tesztelo programot. De sajnos mint kiderult, a SerialPort ezzel a modszerrel nem mukodik.
Most lehetne azt csinalni, amit Jason javasolt, vagy azt, amit en csinaltam, hogy egy TCP servert epitettem a C# programba. Utobbi kb 10 perc volt, mivel olyat mar csinaltam. Elobbit bevallom nem teljesen ertem, ugyanis meg soha nem csinaltam class libraryt.

Tehat most ott all a dolog, hogy adott egy TCP server, amire csatlakozva tudom iranyitani a motrot. Talaltam egy jsocket nevu libraryt, amivel, a pelda alapjan, konnyen lehet javascriptol csatlakozni egy TCP serverhez. Ha sikerul modositani a streamelest vegzo programban a html reszt - ennek meg nem neztem utana -, es hozzaadni 2 gombot, akkor nincs szukseg egy plusz webserver mukodtetesere. Ha nem sikerul, akkor viszont muszaj lesz, es ezzel a verzioval nem nyerek semmit.

Amugy lesz egy Androidos program is hozza, ott viszont elony a TCP socket-es verzio. Egy Webview, ami mutatja a streamet, alatta pedig 2 gomb, ami tcp-n csatlakozik a C# programhoz.

De megprobalom majd a class library keszitest is (nezegettem egy tutorialt, es az alapjan nem tunik veszesnek a dolog).

Sic Transit Gloria Mundi

A feladat annyi lett volna, hogy kb. fogod a VS-t, csinálsz egy új class library projektet és bemásolod a fenti kódot, lefordítod, majd azt példányosítod le PHP-ben a DOTNET -tel, ha már a SerialPort osztályt nem engedi PHP-ban.

Ehhez képest egy TCPServer létrehozása szerintem sokszorta több munka.

----------------
Lvl86 Troll

Miutan itt eleg reszletesen leirtatok, hogy kb mit is kell csinalni, es en is utanaolvastam kicsit neten, belatom, hogy tenyleg nem tunik nagy feladatnak. Viszont mikor eloszor olvastam, akkor kb kinainak hangzottak szamomra a leirtak...
Mig TCPServert mar csinaltam korabban, igy azt csak keszen at kellett vennem a masik projektbol. Amugy tenyleg nagyobb munka lenne megcsinalni ezt, foleg, hogy multiclient legyen, es minden kliens kulon szalon legyen kezelve...

Sic Transit Gloria Mundi

Miert nagyobb ganyolas egy TCP socketre csatlakozni, mint leforditani egy class library-t strongly-named NET assemblieskent, beregisztralni, majd azt php-bol meghivni?

Mert az igazi "nemgányolás" az lenne, ha a php-ba raknál soros portot natívan kezelő modult. Csak ugye abból nincs rendes, ami tudná, amit szeretnél...

Amúgy meg erre a feladatra python a mondás. Ahhoz van multiplatform natív soros port kezelő (jó), meg kb. mindent tud, amit a php valaha tudhatott, csak annál sokkal jobban, meg még többet.

Talaltam egy nativ soros port modult php-hez, de az nem tudta a BREAK state-t. Irtam a szerzojenek, hogy lenne-e kedve bele tenni, par sor lenne az egesz, de azt mondta, hogy csak akkor, ha megveszem a fizetos verziot. De mivel nem valamiceges projektrol van szo, igy nem er meg nekunk 30 eurot, foleg, hogy maskent is megoldhatom.

Dolgoztam egy keveset pythonban, ugyhogy nem all messze tolem, es szeretem is. A pythonos megoldast milyen modon gondoltad: php helyett hasznalni apache-ban mod_python modullal?

Sic Transit Gloria Mundi