トップ回答者
cl で参照するアセンブリの明示的な指定方法

質問
-
うぇねと申します。
今、cl でリンクするアセンブリが指定できなくて困っております。
コード中に
#using <System.dll>
#using <System.Windows.dll>
と、アセンブリを取り込んでいるソースを以下のようなコンパイル・オプションでビルドしました。
cl /clr app.cpp /X /LD /FU "$(ProgramFiles)\Microsoft Silverlight\2.0.30226.2\System.dll" /FU "$(ProgramFiles)\Microsoft Silverlight\2.0.30226.2\System.Windows.dll"
これを VisualSturdio 2008 の VC フォルダにある vcvarsall.bat を実行したコマンド・プロンプト上で実行すると、/FU で明示したSystem.dll や System.Windows.dll を参照せず、Windows のシステムフォルダに配置されている v2.0.50727\System.dll を優先してインポートしてくれます。
/AI オプションでアセンブリのパスを指定しても同様にシステムフォルダに配置されているアセンブリが参照されます。
C# や VB では MSBuild のターゲット指定で Silverlight 用のアセンブリを指定できているようです。
C++/CLI でも、Project をインポートするなどしてシステムのアセンブリに優先してインポートする方法はないでしょうか?
よろしくお願いいたします。
回答
-
どうやら、解決策が見つかったようです。フィードバック投げた直後だってのに orz
カレント・ディレクトリに参照対象となるアセンブリを配置することで、システム・ディレクトリに優先して参照できる模様です。
カレント・ディレクトリを次のような構成にして
app.cpp
mscorlib.dll
System.dll
System.Core.dll
cl /clr
ure app.cpp /LD
と実行することで、app.dll が作成されました。
これまでがいろいろとワーニングを出していたにもかかわらず、何のエラーも出ないため、逆に正常にアセンブリが参照できているかどうか不安ですが、これですこし試してみたいと思います。
-
Veneficus さんからの引用 現象としては少し意味が違いまして、/AI や LIBPATH、#using や /FU で指定しても、mscorlib.dll や System.dll などが、.NET Framework システムディレクトリ以外のものを参照してくれないという状態です。 隠しオプション /d1clr:nostdlib でなんとかなりませんかね?
すべての返信
-
/FUオプションがあるときは#usingいらないはずですが…。
http://msdn.microsoft.com/ja-jp/library/81ex1b0a.aspx
/FUオプションを優先して、#usingをさせたくないということなのでしょうか。
現状の動きの解釈
・/FUオプションでSilverlightのSystem.dllを参照
・#usingディレクティブで.NET 2.0のSystem.dllを参照
・System.dllが2つ参照されることで、曖昧さが解決できなくてエラー
#usingのアセンブリの検索順は下記を参照。
http://msdn.microsoft.com/ja-jp/library/yab9swk4.aspx
A path specified in the #using statement.
The current directory.
The .NET Framework system directory.
Directories added with the /AI compiler option.
Directories on LIBPATH environment variable.
-
返答ありがとうございます。
現象としては少し意味が違いまして、/AI や LIBPATH、#using や /FU で指定しても、mscorlib.dll や System.dll などが、.NET Framework システムディレクトリ以外のものを参照してくれないという状態です。
試してみたことは、上述の /FU での指定(#using時の依存解決する対象を強制変更するフラグ)、#using にフルパスで参照するアセンブリを指定、カレントにアセンブリをコピーして #using 参照、/AI での参照先指定、LIBPATH の修正です。
曖昧さが解決できずにエラーになっているわけではなく、.NET Framework システムディレクトリのアセンブリで#usingを解決してしまい、mscorlib.dll や System.dll が Silverlight 用に修正されているアセンブリを参照できず、Silverlight のクラスを解決するときに、既存の.net fx のアセンブリを探してエラー、となっております。
cl は C++/CLI のアセンブリ解決では必ず現状システムのアセンブリを優先してしまう仕様になっているということなのでしょうか。フィードバックに投げる前に確認できることは確認しておこうと思いまして。
Code Snippetc:\workspace\silverlight\workarea\sl2samples\test\app\system.dll : warning C4945: 'DescriptionAttribute' : 'c:\workspace\silverlight\workarea\sl2samples\test\app\system.dll' からシンボルをインポートできません : 'System::ComponentModel::DescriptionAttribute' は既に別のアセンブリ 'System' からインポートされています。
c:\program files\microsoft silverlight\2.0.30226.2\system.dll : 'System::ComponentModel::DescriptionAttribute' の宣言を確認してください。
最初の型を使用します。現在の型を使用するにはインポートされたアセンブリを
再オーダーしてください。
型 'System.ComponentModel.DescriptionAttribute' をアセンブリ 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' からインポート中に、この診断が発生しました。エラーメッセージはこのようになります。
クラス'System::ComponentModel:
escriptionAttribute' をカレントにコピーした System.dll から解決しようとして、すでにシステムディレクトリの System.dll で解決されているために、同名のクラスを解決できずにいます。
む、これは namespace 指定で回避できるかも。
もう少し足掻いてみます。
-
足掻いて無理だと悟ったうぇねです。
や、無理かと思います。RootVisual の追加の仕方がコントロールを生成して、対応する xaml をアダプトするやり方だったので、所詮は同じ IL だから xap に同じ構成を実現してやれば、と甘く見ていましたが、コンパイル時にシステムディレクトリが何よりも先に解決されてはどうしようもないです。
VisualStudio 2008 では参照対象となる .net fx のバージョン指定が可能であるため、ライブラリの参照先指定は同様のメカニズムで対応できるかと考えていたのですが、あくまでも CLR 2.0 のシステム上で動くものが前提のようです。
これができれば、.net fx 1.0 の IL をC++/CLI で、という罠のようなこともできたかもしれなかったのですが、出力する IL の後方互換性を持っていない(持たせていない)のかもしれません。
とりあえず、無理そうなのでフィードバックに投げてきます。
ありがとうございました。
-
どうやら、解決策が見つかったようです。フィードバック投げた直後だってのに orz
カレント・ディレクトリに参照対象となるアセンブリを配置することで、システム・ディレクトリに優先して参照できる模様です。
カレント・ディレクトリを次のような構成にして
app.cpp
mscorlib.dll
System.dll
System.Core.dll
cl /clr
ure app.cpp /LD
と実行することで、app.dll が作成されました。
これまでがいろいろとワーニングを出していたにもかかわらず、何のエラーも出ないため、逆に正常にアセンブリが参照できているかどうか不安ですが、これですこし試してみたいと思います。
-
ところで、その成果物はMicrosoft.VisualCへの参照を含む等、Silverlightにないアセンブリへの参照がありそうですが、問題ないのでしょうか?
その辺が気にはなります。
(メタデータでそれらしいと判断しているので指摘自体が間違っているかもしれません)
.module extern MSVCR90.dll
.module extern KERNEL32.dll
.module extern msvcm90.dll
.assembly extern mscorlib .ver 2:0:5:0.assembly extern System .ver 2:0:5:0
.assembly extern Microsoft.VisualC .ver 8:0:0:0
.assembly extern mscorlib as mscorlib_3 .ver 2:0:0:0
-
どうも、うぇねです。
私もできたアセンブリを確認して、それが気になっていたのですが、どうも大丈夫そうです。
作成した DLL を適切な名前に変更し、AppManifest.xaml を用意、xap ファイルを作成しました。
Chiron を使ってブラウザ表示させたところ、とりあえず、空白のページですがエラー無くSilverlightコンポーネントに起動に成功しました。本当に該当のアセンブリがロードされているのか心配だったのですが、ちょうど、リソースとして指定していた別のXAMLファイルのロードに失敗してエラーが出たので、C++/CLI で作成したアセンブリが Chiron 上でロードされ、Silverlight のアセンブリとして利用できることが確認できました。
この Silverlight アプリケーションが Windows 以外のプラットフォームで動くかどうかまでは確認できていませんが、少なくとも Windows プラットフォーム上では Silverlight アプリケーションとして振る舞うことは検証できました。
まぁ、とはいえ Silverlight のアプリケーションを C++/CLI で開発するのは、(愛すべき)おばかさんだと思います(笑)。
もう少し、コードの中身を追加して、他のプラットフォームでも検証可能なページを作成したいと思います。
おつきあいありがとうございます。
-
Veneficus さんからの引用 現象としては少し意味が違いまして、/AI や LIBPATH、#using や /FU で指定しても、mscorlib.dll や System.dll などが、.NET Framework システムディレクトリ以外のものを参照してくれないという状態です。 隠しオプション /d1clr:nostdlib でなんとかなりませんかね?
-
Nyaruru さん、こんにちは。
試してみました。
ローカルから Silverlight の DLL を削除して、次のようにコンパイルを行いました。
cl /clr: pure app.cpp /LD /d1clr:nostdlib /AI "%SilverlightPath%"
これを実行したところ、無事、アセンブリが作成されました。毎回、コピーをするよりもこれで Makefile を作ったほうが断然楽ですね。自分の作業にはこれで行こうかと思います。人にはお勧めできませんね。
ただ、US のフォーラムでも言われていましたが、あくまで非公開オプションでいつなくなるとも知れないオプションなので、コンパイラチームには正式なサポートをお願いしたいと思います。
ドキュメントとコンパイラの振る舞いが違うのは、やっぱり問題ですので。
ありがとうございました。