8

私は PHP の初心者で、今日DOTNETクラスを発見しました。
そこで私はマニュアルを勉強し、Web をサーフィンしていくつかの例を見つけ、最終的にテスト アプリを作成しました。

  1. Framework 4.0 Client Profile を使用して新しい DLL を作成
  2. 厳密な名前のキーでアセンブリに署名した
  3. アセンブリを COM 可視としてマーク

これは私が書いたテストコードです

using System;

namespace CSharpCOM
{
    public class CSharpCOMClass
    {
        public string Base64(string s)
        {
            return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(s));
        }
    }
}

アセンブリをコンパイルし、GAC に登録しました ( gacutil /if fullpath\CSharpCOM.dll)。
使えばgacutil /l CSharpCOM分かる

La cache di assembly globale contiene gli assembly seguenti:
csharpcom, Version=1.0.0.0, Culture=neutral, PublicKeyToken=beb607ae770f5750, processorArchitecture=MSIL

要素数 = 1

だから、すべてがうまくいくようです。
次に、この基本的な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";
}
?>

何をしようとしても、Apache でホストされているページを読み込んでいます ( http://localhost/test01/dotnet.php) いつも取得します

キャッチされた例外: .Net オブジェクトのインスタンス化に失敗しました [CreateInstance] [0x80070002] 不可能なファイル固有のファイルです。
翻訳可能性: 指定されたファイルが見つかりません

もう 1 つ: いくつかの例 (ここでは非常に基本的なもの) を使用すると、アセンブリ (登録されている場合) は で見つかるはず%windir%\assemblyですが、でしか見つけることができません%windi%\Microsoft.NET\assembly\GAC_MSIL\CSharpCOM\v4.0_1.0.0.0__beb607ae770f5750: これは正しいですか? 最初のディレクトリに置かないのはなぜですか?

詳細: 別のフレームワーク プロジェクトを作成して .NET 参照を追加しようとすると、アセンブリが見つかりません。これは、このアセンブリを PHP から読み込めないことに関係していますか?

最後のメモ: Windows XP Professional SP3 32bit と Windows Seven Enterprise 64bit で試してみました

更新:
これは機能します:

$form = new DOTNET('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form');

しかし、これはしません:

$form = new DOTNET('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form');`  

PHP がフレームワーク 2.0 アセンブリしかロードできない可能性はありますか?

4

2 に答える 2

7

このバグ レポートによると、DOTNET クラスは .NET 4.0 DLL をロードしていません。.NET 4.0 の新しいライブラリを使用していない場合は、プロジェクトのプロパティを開き、[アプリケーション] タブで [ターゲット フレームワーク] を [.NET Framework 3.5 クライアント] に変更して、.NET 3.5 以下をターゲットにすることができます。プロフィール"

DLL を GAC にインストールすると、DLL は CLR 2.0 GAC にインストールされ、PHP の DOTNET クラスを使用してロードできるようになります。

于 2012-04-18T14:50:45.177 に答える
6

NetPhp ( https://github.com/david-garcia-garcia/netphp ) と呼ばれるライブラリがあり、次のことが可能になります。

  • 任意の .Net バイナリ (COM Visibility がなくても) と、CLR4 を含む任意のバージョンの .Net フレームワークを使用
  • PHP クラス モデルをダンプする
  • PHP クラス モデルの生成から直接 .Net コレクションを反復処理し、.Net エラーを適切に処理できるネイティブ PHP 例外に .Net エラーを自動的に伝播します。
  • ネイティブの列挙型と静的メソッドにアクセスします
  • パラメーターでクラス コンストラクターを使用する
  • 単一のアプリケーションであるかのように、.Net および PHP コードを同時にデバッグします。

ここにコード サンプルを含むプロジェクトがあります。

https://github.com/david-garcia-garcia/netphp-sample

NetPhp を使用したコードは次のようになります。

$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;
于 2016-01-10T16:50:55.063 に答える