C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: COMを通じての開発手順について


(過去ログ 108 を表示中)

[トピック内 18 記事 (1 - 18 表示)]  << 0 >>

■64298 / inTopicNo.1)  COMを通じての開発手順について
  
□投稿者/ howling (91回)-(2012/11/22(Thu) 12:43:04)

分類:[.NET 全般] 

いつもお世話になっております。

開発環境:Windows7 / VS2010 / C#

現在、C#でFormを作成し、そのウィンドウハンドルをC++側に渡してC++がそのウィンドウに表示する、
なんていうことをしています。

ウィンドウハンドルを取得する関数をC++側に呼んでもらうために、
このC#のプロジェクト内にあるAssemblyInfo.csにて、
ComVisibleをtrueに指定しています。

さて、このC#プロジェクトにおいて、別のDLLを使用したいといった状況になったのですが、
このDLLのサンプルコードはあるのですが、ソースコードが見つからず、
DLLのみで開発を続けようと思っております。

サンプルプロジェクトを1つ作り、このDLLを用いて予想通りの挙動を得られたのですが、
本来のC#プロジェクトに入れた場合に、
どうもアセンブリを発見できず、実行時エラーになってしまう状態になりました。

エラー内容:
 ファイルまたはアセンブリ '「ライブラリ名」, Version=1.00, Culture=neutral,PublicKeyToken=xxxxxxxx(書いていいのかわからんのです)'、
 またはその依存関係の1つが読み込めませんでした。指定されたファイルが見つかりません。

Dllだけですと、tlbファイルの作成はできるものの、GACUtilコマンドで失敗しますので、どうしたものかと…。

何か良い方法などご存知ありませんか?
AssemblyInfo.csにComVisibleをtrue指定しているだけなので、別プロジェクトを作って入れればうまくいったりしないのかな?とか淡い期待を抱いていますが…。
引用返信 編集キー/
■64305 / inTopicNo.2)  Re[1]: COMを通じての開発手順について
□投稿者/ オショウ (38回)-(2012/11/22(Thu) 17:50:51)
> 現在、C#でFormを作成し、そのウィンドウハンドルをC++側に渡してC++がそのウィンドウに表示する、
> なんていうことをしています。
>
> ウィンドウハンドルを取得する関数をC++側に呼んでもらうために、
> このC#のプロジェクト内にあるAssemblyInfo.csにて、
> ComVisibleをtrueに指定しています。

  ウィンドウハンドルをC++ Dll側に渡す?
  それともC++ Dll側から探させている?

  ドッチ?
  それと、C++ Dll側で探させている場合、どんなAPI使っているの?

  通常、C#側からウィンドウハンドルを渡すならComVisibleは関係ない・・・

> さて、このC#プロジェクトにおいて、別のDLLを使用したいといった状況になったのですが、
> このDLLのサンプルコードはあるのですが、ソースコードが見つからず、
> DLLのみで開発を続けようと思っております。
>
> サンプルプロジェクトを1つ作り、このDLLを用いて予想通りの挙動を得られたのですが、
> 本来のC#プロジェクトに入れた場合に、
> どうもアセンブリを発見できず、実行時エラーになってしまう状態になりました。

  それも、C++ Dllなんですか?
  なら、Win32 API で作成されたDllなのか、MFC Dll なのか・・・

  それと、そのDllを呼び出す方法は、Declareしているの?
  それともCOM参照?

> エラー内容:
>  ファイルまたはアセンブリ '「ライブラリ名」, Version=1.00, Culture=neutral,PublicKeyToken=xxxxxxxx(書いていいのかわからんのです)'、
>  またはその依存関係の1つが読み込めませんでした。指定されたファイルが見つかりません。

  ただ単にそのDllが必要とする別のDllがPath検索上に無いだけではない
  でしょうか?

  そのDllが他のどんなDllを必要としているのか、DependencyWalkerで調べられては?
  (DEPENDS.EXEですネ)

> Dllだけですと、tlbファイルの作成はできるものの、GACUtilコマンドで失敗しますので、どうしたものかと…。

  GACUtilで登録できるものは、アセンブリを持つものを登録する為のものですので、
  何で作られたDLLを登録しようとされているんですか?

  登録できるものを登録しようとして失敗するのは管理者権限が無いだけかと。

以上。
引用返信 編集キー/
■64306 / inTopicNo.3)  Re[1]: COMを通じての開発手順について
□投稿者/ とっちゃん (22回)-(2012/11/22(Thu) 17:56:06)
とっちゃん さんの Web サイト
No64298 (howling さん) に返信

> さて、このC#プロジェクトにおいて、別のDLLを使用したいといった状況になったのですが、
> このDLLのサンプルコードはあるのですが、ソースコードが見つからず、
> DLLのみで開発を続けようと思っております。
>
> サンプルプロジェクトを1つ作り、このDLLを用いて予想通りの挙動を得られたのですが、
> 本来のC#プロジェクトに入れた場合に、
> どうもアセンブリを発見できず、実行時エラーになってしまう状態になりました。
>
> エラー内容:
>  ファイルまたはアセンブリ '「ライブラリ名」, Version=1.00, Culture=neutral,PublicKeyToken=xxxxxxxx(書いていいのかわからんのです)'、
>  またはその依存関係の1つが読み込めませんでした。指定されたファイルが見つかりません。
>
> Dllだけですと、tlbファイルの作成はできるものの、GACUtilコマンドで失敗しますので、どうしたものかと…。
>
何度か読み直してみたのですが、正直何がしたくて何が問題なのかよくわかりません。

DLLのサンプルコードとはなんですか?
どんなDLLを使おうとしてエラーが出ているのでしょうか?
GACUtilコマンドに失敗って、そのDLLをどういう形での利用を想定しているのでしょうか?
通常、COMモジュールとしてグローバルに登録するものは、GACではなく、専用フォルダにインストールして
システムに登録して利用します。
GACにインストールしてもCOMとして使えるようになるわけではありません。


> AssemblyInfo.csにComVisibleをtrue指定しているだけなので、
ComVisible にしているので、きちんと対処しないとグダグダになります。。。
というか、ComVisible = true にするのは、COMコンポーネントとして公開する側が行うものです。

Comクライアントとして利用するだけなら、ComVisible=falseで利用できます。
引用返信 編集キー/
■64307 / inTopicNo.4)  Re[2]: COMを通じての開発手順について
□投稿者/ howling (93回)-(2012/11/22(Thu) 19:07:02)
2012/11/22(Thu) 19:18:41 編集(投稿者)

オショウ さん

ご返信ありがとうございます。
書き方がわかりづらく、申し訳ありません。
1つ1つお答えしますね。

>   ウィンドウハンドルをC++ Dll側に渡す?
>   それともC++ Dll側から探させている?
>
>   ドッチ?
>   それと、C++ Dll側で探させている場合、どんなAPI使っているの?
>
>   通常、C#側からウィンドウハンドルを渡すならComVisibleは関係ない・・・

C#側にGetWindowHandleみたいな関数を設けておいて、これをC++に公開しています。
ですので、前者になります。
ComVisibleをtrueにする必要は無いのでしょうか…?
これをせずにやる方法をまだ知りません。
ここを参考に、snkファイル作成→DLL作成→GACUtil&RegAsm呼び出しをしています。

(サイト自体はUTF-8で書いてあるのですが、文字コード書いてないらしく、文字化けします。お手数ですが変換してください。)
http://okachibi.web.fc2.com/dotnet/call_csdll_01.html

>   それも、C++ Dllなんですか?
>   なら、Win32 API で作成されたDllなのか、MFC Dll なのか・・・

いいえ、こちらはC#です。
具体的に名前を挙げますが、SharpSVNというライブラリを使わせて頂こうかなと。

>   それと、そのDllを呼び出す方法は、Declareしているの?
>   それともCOM参照?

このDllを呼び出す手順は現在のところ、
ComVisibleをtrueに設定しているC#プロジェクトの参照設定にDLLを追加しているだけです。
おそらくは、これもGACUtilとRegAsmを行う必要があるものと認識しているのですが、
ここでSharpSVNはCOMに公開していないDLLのため、
「何も公開していないけれども成功」といったような状態が返ってきます。

>   ただ単にそのDllが必要とする別のDllがPath検索上に無いだけではない
>   でしょうか?
>
>   そのDllが他のどんなDllを必要としているのか、DependencyWalkerで調べられては?
>   (DEPENDS.EXEですネ)

むむむ…?
もしかするとそうかもしれないですね。
確かに上で書いたDLL追加は、SharpSVN.DLLしか追加していないのですが、
このDLLの周囲には他にもDLLがいくつかあったはず。
これは調べてみます。

>   GACUtilで登録できるものは、アセンブリを持つものを登録する為のものですので、
>   何で作られたDLLを登録しようとされているんですか?
>   登録できるものを登録しようとして失敗するのは管理者権限が無いだけかと。

うーん…ここも理解してませんね。
というか、ここを理解せずに来ているのは危ない気がします。うーむ。
「アセンブリを持つもの」の定義がさっぱりなのです。

上記に貼り付けたURLしか方法を知らないのでこうなってしまっているのですが、
実は他のもっと良い方法があるのでしょうか…?

実際のところ、C#がC++に公開しているのはウィンドウハンドルだけではありません。
C#で表示したウィンドウがいくつかあり、その1つにC++で描画を行っている状態です。
で、この「いくつか表示したウィンドウ」の中でユーザーが情報を入力し、
C++側がその変更に応じて値をC#側から取得しているといった流れです。

簡単には以下のような感じを想像していただけると。

C#側
//フォームの表示
void DrawForm()
{ MyForm.Show(); }
//値の取得
int GetParam()
{
if(m_bChangeFlag == true)
{
m_bChangeFlag = false;
}
return m_iParam;
}
//値の変更有無
bool IsChangeParam()
{
return m_bChangeFlag;
}

//m_bChangeFlagはユーザーの値入力時にtrueとなるだけのもの
//m_bChangeFlagはユーザーに変更されることがある値
//MyFormは表示するウィンドウ


引用返信 編集キー/
■64308 / inTopicNo.5)  Re[2]: COMを通じての開発手順について
□投稿者/ howling (94回)-(2012/11/22(Thu) 19:15:19)
No64306 (とっちゃん さん)

まずはご返信頂きありがとうございます。

> 何度か読み直してみたのですが、正直何がしたくて何が問題なのかよくわかりません。

これ、すみません…。
やりたいことというか、やっていることはオショウさんへのレスを見て頂けると助かります。

> DLLのサンプルコードとはなんですか?

これは、自分でC#のプロジェクトを1個作って、サンプルでSharpSVNのDLLを用いて動かした物です。

> どんなDLLを使おうとしてエラーが出ているのでしょうか?

SharpSVNになります。要はソース管理何か欲しいよねーってことだったんですが。

> GACUtilコマンドに失敗って、そのDLLをどういう形での利用を想定しているのでしょうか?
> 通常、COMモジュールとしてグローバルに登録するものは、GACではなく、専用フォルダにインストールして
> システムに登録して利用します。
> GACにインストールしてもCOMとして使えるようになるわけではありません。

オショウさんのレスに書いたURLを参考にやってしまったので、そうなっているという状態です。
C++とC#で相互に呼び出せるようにしたいよねーというだけの話ですから、
専用フォルダにインストールして利用する?方が良いのかもしれませんね。

> ComVisible にしているので、きちんと対処しないとグダグダになります。。。
> というか、ComVisible = true にするのは、COMコンポーネントとして公開する側が行うものです。
> Comクライアントとして利用するだけなら、ComVisible=falseで利用できます。

はい。C#側のみ公開しています。
C++側は特に公開もしていません。
ですので、上に「相互に呼び出せるようにしたい」と書いたものの、
現状はC++側からC#を呼び出しているだけ、となります。

COMを使用せずに同じことができるのであれば、そっちの方が良いのかなと思います。(改変の必要は当然ありますが)
何かご存知でしょうか?
引用返信 編集キー/
■64309 / inTopicNo.6)  Re[3]: COMを通じての開発手順について
□投稿者/ howling (95回)-(2012/11/22(Thu) 19:31:34)
お二人のご意見を頂きまして、

・COMをそもそも使わなくてもC#で作成したDLLをC++から呼べそう(デバッグもできそう?)
・COMを使用する必要性を理解していない
・アセンブリに関しての知識が薄い

という感じを受けました。

実は、今日1日かけてほぼ進まなかったので、
一旦COM公開していないC++側でSVNを使えば良いかという話で進んでいます。
ただ、この方法の方が回りくどいので、できれば避けたいです。
おそらくはこのまま進んだ場合、以下のような流れになるかと思います。

1.C#(フォーム表示)側で「SVNに関する処理をして欲しい状態」になる(が、C#側は何も気にせずそのまま処理しとく)
2.C++側から「SVNに関する処理をして欲しい状態」になっているかどうか(戻り値bool)をC#側に聞く
3.これがtrueの場合にのみ、C++側から「SVNに関する処理」が何か(enumで定義した値)と、対象ファイルまたはフォルダ(string)を取得。
4.C++側でSVN処理を行う。
5.(C++側から、C#側の「SVNに関する処理をして欲しい状態」になっているかどうかのフラグを下ろす関数を呼ぶ)

C#側で「SVNに関する処理をして欲しい状態」になった時に、
この処理が終了したかどうかを示すフラグを持つかどうかによって誤差はありますが、
それにしても微妙な流れになるかなと…。

ちなみにSharpSVNを使った場合、

1.C#(フォーム表示)側で「SVNに関する処理をして欲しい状態」になったらSVN処理を行って、処理に応じて表示を行う

だけで済みます。(そりゃそうか…)

結構諦め気味で進んでいたのですが、どうにかなるのであればそっちの方が良いです。
是非教えて頂けると非常に助かります。(ここ数日の努力が…!)

引用返信 編集キー/
■64312 / inTopicNo.7)  Re[3]: COMを通じての開発手順について
□投稿者/ オショウ (39回)-(2012/11/22(Thu) 22:48:13)
> 実際のところ、C#がC++に公開しているのはウィンドウハンドルだけではありません。
> C#で表示したウィンドウがいくつかあり、その1つにC++で描画を行っている状態です。
> で、この「いくつか表示したウィンドウ」の中でユーザーが情報を入力し、
> C++側がその変更に応じて値をC#側から取得しているといった流れです。

  ようやく解ってきたというか・・・

  C#のフォーム上のコントロールに、C++側から描画を行う・・・
  これってかなり無謀なやり方だと思います。が、ウィンドウハンドル
  だけでC++側から行わせるのは、実際にありかもしれませんが予期せ
  ぬ問題が出るかもしれません。

  やり方は別として・・・
  スマート?(と私は思っている)な方法としては
  1. GUIは、C#
  2. DLLは、C++
  とした場合、C# と、C++ DLLを繋ぐラッパーDLLを、C++ CLI で作成して、
  マネージとアンマネージ(ネイティブも)を繋ぐのが、よいのではないで
  しょうか。

  そうすれば、C# => C++ CLI DLL は、参照設定のみ
  C++ CLI => C++ DLL は、LoadLibrary ででもよいし・・・

  ソースコードが無いC++ DLLのものは論外ですが、すべてC++ CLI で、DLL
  化した方が、この際、安全・・・と思いますが。

以上。参考まで

引用返信 編集キー/
■64324 / inTopicNo.8)  Re[4]: COMを通じての開発手順について
□投稿者/ とっちゃん (24回)-(2012/11/26(Mon) 13:44:47)
とっちゃん さんの Web サイト
No64309 (howling さん) に返信

No64308
>SharpSVNになります。要はソース管理何か欲しいよねーってことだったんですが。

SVNを使って、ソース管理をしたいのですか?
えーっと。。。それをなぜ自作プログラムから呼び出したいのでしょう?
いや、もちろん機械的なアクセス手段がほしいので。。。というのはアリですが。
それならそういうことを書くだろうし。。。

状況がよくわからないというか、何をしたくてSVNをプログラムから制御しようとしているのかがさっぱりわからない。。。


> 結構諦め気味で進んでいたのですが、どうにかなるのであればそっちの方が良いです。
> 是非教えて頂けると非常に助かります。(ここ数日の努力が…!)
>
ということで、とりあえず SVN についてはおいておいて...

使いたい機能が、.NET のアセンブリとして一般公開されていて(今回の場合は、SharpSVN)
それを、C++のプログラム(自作)から使いたいのだがどうすればいいか?

ということでしょうか?

それとも、
使いたい機能が、.NET のアセンブリとして一般公開されていて(今回の場合は、SharpSVN)
既にC#のプログラムから使えている状況があり、

この中に、C++のプログラム(DLL)を追加してそこからも、アセンブリを操作したい
ということでしょうか?


前者なら、C++のプログラムを /CLR スイッチをつけてビルドすれば、C#で利用するのと
同様にC++からも利用できます。

後者も基本的には、/CLR スイッチをつけて、C++/CLI としてビルドしてやることで
C#と同様、.NET アセンブリになるため、そのまま直接的に参照・利用ができます。


既存の修正不可能な、Native モジュールがあり、それをC#(.NET アプリ)から使いたい
という場合は、それなりに面倒な部分はありますが、自作のC++プログラムを
C#でも使いたい(あるいはその逆)なら、/CLR スイッチ一つですべて Managed な世界に
所属させることができます。

多分、すごく難しく考えすぎている気がします。
COMの利用は否定しませんが、この先長く使っていくつもりなら、COMにするのは最後手段
のつもりでいいと思います。
引用返信 編集キー/
■64326 / inTopicNo.9)  Re[4]: COMを通じての開発手順について
□投稿者/ howling (97回)-(2012/11/26(Mon) 15:43:18)
オショウ さん

うーん、今のところ特に問題無くプロジェクト自体は進行しています。
もしかしたら設計がマズいかもしれない…くらいの考えは頭の片隅に置いて作業したいと思います。
さすがに、今からそれをやると全体の話をもう1度し直さなければなりませんし、
ちょっと難しい状況です。
問題が出てどうしようもない、ということになったらそのように変更提案を出したいと思います。

ありがとうございました。
引用返信 編集キー/
■64328 / inTopicNo.10)  Re[5]: COMを通じての開発手順について
□投稿者/ howling (98回)-(2012/11/26(Mon) 16:13:17)
> SVNを使って、ソース管理をしたいのですか?

はい。実はC#で表示しているFormの中にファイルリストという物がありまして、
こちらにアクセスする場合にファイルのロック/アンロックを行うことで、
排他制御を行いたいと考えております。
  (例に挙げたソースコードで言うならば、m_iParamだけ書かれているファイルを排他制御したいということ)

そこで、SVNが普段使っているソース管理ツールとして挙がったため、
できればFormのイベントを直接受け取るC#側でSVNを使いたいと思い、
SharpSVNに辿り着きました。

> 使いたい機能が、.NET のアセンブリとして一般公開されていて(今回の場合は、SharpSVN)
> それを、C++のプログラム(自作)から使いたいのだがどうすればいいか?
>
> ということでしょうか?
>
> それとも、
> 使いたい機能が、.NET のアセンブリとして一般公開されていて(今回の場合は、SharpSVN)
> 既にC#のプログラムから使えている状況があり、
>
> この中に、C++のプログラム(DLL)を追加してそこからも、アセンブリを操作したい
> ということでしょうか?

  えー、今回この使いたい機能というのがSharpSVNですので、そう書きますね。
 また、C#が示すアセンブリというのがしっかり認識できていないため、アセンブリという書き方はしないでおきます。
  
  SharpSVNはソースファイル(プロジェクトも含む)が見つからず、DLLのみ見つかっている状態です。
  このDLLをC#から参照して、正常に動作するテストまでは既に終えております。
 が、C#とC++を両方プロジェクトに組み込んでいるソリューションでは、まだうまく行っていません。
これは、C#側でDLLを作り、それをCOMに公開することでC++から使えるようにしているからで、
C#側でSharpSVNのDLLを参照設定に入れた場合、SharpSVNはCOMへ公開する許可が下りていない為だと思っております。

  書いて頂いた内容を読む感じですと、
 C++側からC#のプログラムを読む前提で書かれているように思えますが、それは間違いで、
C#側でSharpSVNを参照設定にした上で作成したDLLを、C#から読み取りたいという状況です。
(こちらの認識違いでしたら申し訳ありません)

/CLRスイッチをC++側で付けてC++のプロジェクトをコンパイルした際には、
C#からManagedコードとして読み取ることができるのかな?と思いました。
C#にも同様に/CLRスイッチをつける???などでうまいことC++側へ公開することはできるのでしょうか?

なんか書いていて自分でもわかりづらい日本語なのですが、難しいですね…わからない点があったらまた答えますので、
宜しくお願い致します。

引用返信 編集キー/
■64330 / inTopicNo.11)  Re[6]: COMを通じての開発手順について
□投稿者/ Azulean (71回)-(2012/11/26(Mon) 22:35:36)
ずっと様子見してたんですが、要領を得ない状態が続いているのは変わらないというのが正直な感想です。
なぜなのかは断言できませんが、本当に必要な条件とそうではないものがごちゃ混ぜになっていて、質問者と回答者の前提としているものが違っているのではないか?と、私個人は思っています。
(COM って必要な条件なんですか? それとも、COM じゃないとできないと考えて作ってきたのでその資産を前提としたいのですか?)


No64328 (howling さん) に返信
> これは、C#側でDLLを作り、それをCOMに公開することでC++から使えるようにしているからで、
> C#側でSharpSVNのDLLを参照設定に入れた場合、SharpSVNはCOMへ公開する許可が下りていない為だと思っております。

アセンブリが見つからないというエラーのことに対して、「SharpSVNはCOMへ公開する許可が下りていない為」というのは推測として間違っているのではないかと思います。
アセンブリが見つからないのは、アセンブリが読み込まれる AppDomain にはアセンブリを探すためのパスが設定されていますが、このパスには COM 登録している C# の DLL があるフォルダーが含まれるとは限りません。(経験上)
このため、COM 登録している C# の DLL と同じフォルダーにあるアセンブリが見つからないといったエラーは起こりえます。
確実にアセンブリを探せるようにする手段は、COM 登録しているアセンブリと、それが必要とするアセンブリすべてを GAC に登録することです。

GAC に登録しようとしてエラーになるのは、厳密な名前がついていないからでしょう。
他者が作った DLL に後から勝手に自分たちの Key で厳密な名前を付与することもできなくはないですが、バイナリに対する改変行為なのでライセンス上認められる行為なのかもきちんと考えるべきでしょう。
ライセンス上、認められていないのであれば COM ベースはあきらめた方がよいかと。


>  C++側からC#のプログラムを読む前提で書かれているように思えますが、それは間違いで、
> C#側でSharpSVNを参照設定にした上で作成したDLLを、C#から読み取りたいという状況です。
> (こちらの認識違いでしたら申し訳ありません)

このブロック、書き間違えていないでしょうか?(読み手に混乱させています)
「C# で作った DLL を C++ で呼びたい」なら、とっちゃんさんがすでに書いているように、C++ 側を C++/CLI にすれば COM など使わずに呼べるでしょう。(両方向書いていますよ?)
もっとも、純粋な C++ ではなくなりますが。


> /CLRスイッチをC++側で付けてC++のプロジェクトをコンパイルした際には、
> C#からManagedコードとして読み取ることができるのかな?と思いました。

C++ 側が Managed になる(か、ハイブリッドになる)ので、.NET のコードを呼ぶことができるし、.NET から呼べるコードを作ることができる。
そう読んでください。


> C#にも同様に/CLRスイッチをつける???などでうまいことC++側へ公開することはできるのでしょうか?


故に、元から Managed の C# に /CLR スイッチなるものはありません。
また、純粋なネイティブ C++ から呼べるようにする方法は COM 以外にはありませんので、差し障りがなければ、C++ 側を C++/CLI に切り換えることで、C#(.NET)に歩み寄る方が楽であると思っています。
引用返信 編集キー/
■64331 / inTopicNo.12)  Re[7]: COMを通じての開発手順について
□投稿者/ howling (99回)-(2012/11/26(Mon) 23:37:34)
Azuleanさん

すみません、色々とご迷惑おかけしております。

> (COM って必要な条件なんですか? それとも、COM じゃないとできないと考えて作ってきたのでその資産を前提としたいのですか?)

COMは必要な条件ではないです。
できれば、COMをはずせるのであればはずしたいです。
が、C++からC#を呼び出す方法を現状それしか知らないために、困っている状態です。
ひとまず、必要な条件としては、C#からSVN関連の何かを呼び出したい、という事のみです。


> アセンブリが見つからないというエラーのことに対して、「SharpSVNはCOMへ公開する許可が下りていない為」というのは推測として間違っているのではないかと思います。
> アセンブリが見つからないのは、アセンブリが読み込まれる AppDomain にはアセンブリを探すためのパスが設定されていますが、このパスには COM 登録している C# の DLL があるフォルダーが含まれるとは限りません。(経験上)
> このため、COM 登録している C# の DLL と同じフォルダーにあるアセンブリが見つからないといったエラーは起こりえます。
> 確実にアセンブリを探せるようにする手段は、COM 登録しているアセンブリと、それが必要とするアセンブリすべてを GAC に登録することです。
>
> GAC に登録しようとしてエラーになるのは、厳密な名前がついていないからでしょう。
> 他者が作った DLL に後から勝手に自分たちの Key で厳密な名前を付与することもできなくはないですが、バイナリに対する改変行為なのでライセンス上認められる行為なのかもきちんと考えるべきでしょう。
> ライセンス上、認められていないのであれば COM ベースはあきらめた方がよいかと。

なるほど…。確かにこのエラー内容でそう判別しきってしまうのは間違いですね。
実際のところ、GACに毎回登録していました。
この場合は、ソースコードがあったためにKeyを作成してコンパイルし直していましたが、
やはりライセンスのことを考えると、あまりそうするべきではなさそうですね。
(とすると、COMベースでやるのはやっぱり諦めないといけなさそうですし、できればそうしたいですね。
現在では商用利用することは無く、社内のみで使用するため、ライセンスに触れることは無いと思いますが、
将来を考えると本当に良いかわかりませんので。)

> このブロック、書き間違えていないでしょうか?(読み手に混乱させています)
> 「C# で作った DLL を C++ で呼びたい」なら、とっちゃんさんがすでに書いているように、C++ 側を C++/CLI にすれば COM など使わずに呼べるでしょう。(両方向書いていますよ?)
> もっとも、純粋な C++ ではなくなりますが。
> C++ 側が Managed になる(か、ハイブリッドになる)ので、.NET のコードを呼ぶことができるし、.NET から呼べるコードを作ることができる。
> そう読んでください。

あ…あれ?見直します。
とすると、既にとっちゃんさんが回答されている内容の通りにやれば良さそうですね…。
こちらはちょっとお時間をください。相談します。

> 故に、元から Managed の C# に /CLR スイッチなるものはありません。

やっぱりそうですよね。
多分無いのではないか?という話はちょっとしてました。

> また、純粋なネイティブ C++ から呼べるようにする方法は COM 以外にはありませんので、差し障りがなければ、C++ 側を C++/CLI に切り換えることで、C#(.NET)に歩み寄る方が楽であると思っています。

こちらの方が良さそうです。それで問題が無ければ、普通(という言い方もおかしいですが)にC#からSharpSVNのDLLを参照設定するだけで動きますね。
実際にやってみてから、またご報告します。

特に、「混乱させている」という部分について、本当に助かりました。
明日以降、少々お時間を頂くことになるかもしれませんが、報告をお待ちください。
ありがとうございました。
引用返信 編集キー/
■64332 / inTopicNo.13)  Re[5]: COMを通じての開発手順について
□投稿者/ howling (100回)-(2012/11/26(Mon) 23:39:30)
とっちゃんさん

すみません、C++でCLRスイッチを付けて、明日取り組んでみます。
こちらでだいぶ混乱してしまい、大変申し訳ございません。
おかげさまで光明が見えました。頑張ります!

少しお時間を頂戴しますが、宜しくお願い致します。
引用返信 編集キー/
■64370 / inTopicNo.14)  Re[6]: COMを通じての開発手順について
□投稿者/ howling (107回)-(2012/11/29(Thu) 20:27:26)
2012/11/29(Thu) 20:40:05 編集(投稿者)

困った…詰まった…。

進捗と一緒に、質問させてください。

とりあえず、サンプルのC#プロジェクトにSharpSVNを参照させ、
そのC#プロジェクトをC++のプロジェクトが参照することで、正常に動作するところまでは行きました。

さて、CLIにするとポインタではなくトラッキングハンドルを主に扱うようになるようなのですが、
ウィンドウハンドルをC#側に渡したい場合に、IntPtrにHWNDから変換できず、困っています。

(自分で書いててようやく解決しました)

単なるキャストで良かった。

CSharpClass->SetWindowHandle(static_cast<System::IntPtr>(GetWindowHandle()));

むしろなぜこれまで通らなかったのか謎。
引き続き頑張ります。
引用返信 編集キー/
■64388 / inTopicNo.15)  Re[7]: COMを通じての開発手順について
□投稿者/ howling (110回)-(2012/11/30(Fri) 12:35:29)
例によって進捗&現状の問題点を記します。
もしご存知の方がいらっしゃいましたら、教えてください。お願いします。

とりあえずコンパイルが通り、実行可能になったのですが、
Formを呼び出した時に「DragDrop登録は成功しませんでした。」
という例外が発生します。
また、ファイルやフォルダのダイアログダイアログが表示されません。

どうも調べたところ、STAThreadを指定しなくてはならないようなのですが、

※ソースはここ
 http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/9e06e3f2-54c0-451d-8d1f-df8e4fd42dcb/
 と、ここにある「たとえば、Windows フォームでドラッグ アンド ドロップなどの要素を初期化するには、シングル スレッド アパートメントを作成し、登録します。」
 という1行。
 http://msdn.microsoft.com/ja-jp/library/5s8ee185(v=vs.80).aspx

C#側ではなく、C++/CLIにて設定する必要があると思っています。
(エントリポイントはC++にあるため)

C++でSTAThreadを指定する場合は、
CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)&CoUninitialize()を呼べば良いのでしょうか。
どうにも指定したのですがうまく行かず、指定する場所が悪いのかと思っています。
プリプロセッサあたりじゃないとマズいような気もするのですが、
設定方法がわかりません。
どなたか教えて頂けませんでしょうか。
引用返信 編集キー/
■64392 / inTopicNo.16)  Re[8]: COMを通じての開発手順について
□投稿者/ とっちゃん (29回)-(2012/11/30(Fri) 13:50:26)
とっちゃん さんの Web サイト
No64388 (howling さん) に返信

> C++でSTAThreadを指定する場合は、

えっと。。。C++のプロジェクトのひな型は何ですか?
それによって設定方法が全く違います。


C++/CLI のプロジェクト(コンソール)なら、

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
...
}
と、C#同様属性を設定するだけで行けると思います。


Native アプリの場合は、リンカーのオプション(詳細設定)で設定します。
詳しくは、STAThreadAttribute クラスのリファレンスをご参照ください。

引用返信 編集キー/
■64393 / inTopicNo.17)  Re[9]: COMを通じての開発手順について
□投稿者/ howling (111回)-(2012/11/30(Fri) 14:03:28)
とっちゃんさん

いつも本当にお世話になっております。

Nativeだった状態から、今ようやく/CLRを付与してC++/CLIになったところ…だと思ってます。
そのため、C++/CLIで、Win32アプリで作成していると思われます。
では、[STAThreadAttribute]を設定してみることにします。
さすがにCoIntializeExを途中から呼んでもダメですよね…。
その場合はMTAになるというようなことも書いてあったので。

結果は追って報告しますね。
毎度毎度すみません…。
引用返信 編集キー/
■64400 / inTopicNo.18)  Re[10]: COMを通じての開発手順について
□投稿者/ とっちゃん (30回)-(2012/11/30(Fri) 15:53:17)
とっちゃん さんの Web サイト
No64393 (howling さん) に返信
> Nativeだった状態から、今ようやく/CLRを付与してC++/CLIになったところ…だと思ってます。
> そのため、C++/CLIで、Win32アプリで作成していると思われます。
> では、[STAThreadAttribute]を設定してみることにします。
あ、書き方がまずかったですね。

元がNativeアプリだった場合(プロジェクトの設定で/clrを有効にした場合)は、
リンカーで設定します。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -