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

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

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

C# から VB6.0のDLLのメッソドを起動


(過去ログ 6 を表示中)

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

■6581 / inTopicNo.1)  C# から VB6.0のDLLのメッソドを起動
  
□投稿者/ mizuki 二等兵(1回)-(2006/09/19(Tue) 13:29:01)

分類:[C#] 


分類:[C#] 

開発環境 Visual Studio 2005
C# から VB6.0のDLLのメッソドを起動したいのですが。

DLL 側の引数が byref の object型になっていて、
各メソッド内で、object.hoge = "" 等
DLL 側で値をセットしています。

下記みたいに記述
object hoge = new clsHoge();

vbdll.vbhoge( ref hoge );

キャスト出来なくて、呼出す事が出来ません。

初心者の質問ですが、ご解説よろしくお願いします。




0
引用返信 編集キー/
■6603 / inTopicNo.2)  Re[1]: C# から VB6.0のDLLのメッソドを起動
□投稿者/ 魔界の仮面弁士 中尉(142回)-(2006/09/19(Tue) 23:59:50)

分類:[C#] 

# 「メソッド」表現と
# 「メッソド」表現が混在しているのが気になりますが、
# それはとりあえず置いといて……。


> DLL 側の引数が byref の object型になっていて、
> 各メソッド内で、object.hoge = "" 等
> DLL 側で値をセットしています。
VB6製DLLにオブジェクトを渡す場合、そのデータ型は、COM として
レジストリに登録されている型である必要があります。指定したクラスが、
COMとして公開されているかどうかを確認してみてください。


> object hoge = new clsHoge();
> vbdll.vbhoge( ref hoge );

こんな感じでどうでしょう。


---------- VB6製DLL (ProgID = "VB6SampleDLL.SampleClass") ----------
Option Explicit
Public Sub vbhoge(ByRef object As Object)
object.hoge = Format(Now, "yyyy-mm-dd hh:nn:ss")
End Sub

'以下は、Marshal.ReleaseComObject の解放が行われたかのチェック用
Private Sub Class_Initialize()
Debug.Print "-->"; ObjPtr(Me)
End Sub
Private Sub Class_Terminate()
Debug.Print "<--"; ObjPtr(Me)
End Sub


---------- C#2.0製コンソールアプリ ----------
using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
VB6SampleDLL.SampleClass vbdll = null;
try
{
object clsHoge = new Hoge();
vbdll = new VB6SampleDLL.SampleClassClass();
vbdll.vbhoge(ref clsHoge);
Console.WriteLine(((Hoge)clsHoge).hoge);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if ((vbdll != null) && Marshal.IsComObject(vbdll))
{
Marshal.ReleaseComObject(vbdll);
}
}
Console.ReadLine();
}
}

[ComVisible(true)]
//[Guid("{1F4F835B-1702-4df9-8AF8-A782713FD1EC}")]
//[ClassInterfaceAttribute(ClassInterfaceType.AutoDual)]
public class Hoge
{
public string hoge = String.Empty;
}
}


0
引用返信 編集キー/
■6625 / inTopicNo.3)  Re[2]: C# から VB6.0のDLLのメッソドを起動
□投稿者/ mizuki 二等兵(2回)-(2006/09/20(Wed) 14:01:45)

分類:[C#] 

No6603に返信(魔界の仮面弁士さんの記事)
返信ありがとうございます。

> # 「メソッド」表現と
> # 「メッソド」表現が混在しているのが気になりますが、
> # それはとりあえず置いといて……。
>
すみません。メソッドのつもりが・・間違えてメッソドになりました。

記述して頂いたソースは、勉強用として、保存して置きます。
あまりにも、簡略な質問だった為に、意図がしっかり伝え切れなかったです。

VBDLL 側
*vbMain の中身
Public Function HogeMethed( LogIF As Object )
LogIF.vbErrorlog.LogMsg = ""

HogeMethed = ""
End Function

*LogIF.cls の中身
public vbErrorlog as object

Private Sub Class_Initialize
set vbErrorlog = new clsvbErrorLog
End Sub
Private Sub Class_Terminate
set vbErrorlog = nothing
End Sub

*vbErrorlog.cls の中身
Public LogMsg As String

上記のような、形になっています。

この状態で、C#2.0から
MainClass.HogeMethed を起動しようとして、
C#側で、Class のネストを作って、引数に入れると
キャストエラーになりました。

VB の DLLは、参照設定にはいってます。

C#2.0 側

namespace Test
{
public class TestMain
{
vbMainClass vbMain = new vbMainClass;

object obj = new object;
LogIF LogInterface = new LogIF;

obj = LogInterface;

vbMain.HogeMethed( obj );
〜〜〜〜〜〜〜〜〜〜〜〜〜の呼出しが理解出来ていないです。
}

public class LogIF
{
object vbErrorLog = new vbError;
}

public class vbError
{
public string LogMsg;
}
}

こんな感じ、呼び出したいのですが・・
VB側のソースが、Object型の呼出しばかりなので、
実態がはるか彼方に定義されていたりするので、
修正も出来ない状態です。

何度もすみませんが、みなさん、よろしくお願いします。

0
引用返信 編集キー/
■6632 / inTopicNo.4)  Re[3]: C# から VB6.0のDLLのメッソドを起動
□投稿者/ 魔界の仮面弁士 中尉(143回)-(2006/09/20(Wed) 15:12:32)

分類:[C#] 

2006/09/20(Wed) 15:24:14 編集(投稿者)

本当に、DLL 側がそのような実装になっているのでしょうか?

サンプルコードだからかも知れませんが、HogeMethed が ByVal ではなく
ByRef になっている理由が不明瞭に感じます。それに、LogIF で、vbErrorlog を
パブリックフィールドとして公開している理由もよくわかりませんでした。


まぁ、それはさておき。

> *LogIF.cls の中身
> *vbErrorlog.cls の中身

VB6 側で生成されたこれらのクラスと、

> public class LogIF
> public class vbError

.NET2.0 側で生成されたこれらのクラスの間には、互換性がありません。
単に、その内容が酷似しているというだけで、実際には別物です。

もしもその ActiveX DLL を参照設定しているのであれば、わざわざ LogIF/vbError の
クラスを C# 側で再定義せずとも、それらを C# 側で利用できるかと思います。
まずはそれを試してください。(VB6側の、各クラスのInstancingプロパティ次第ですが)


そしてもし、COMクラスと互換性のあるマネージクラスを再定義せねばならないのだと
すれば、それらのクラスやメンバに、元のCOMクラスとバイナリ互換性を持たせる
ために、ComVisible を始めとする幾つかの属性――場合によっては、InterfaceTypeや
Guid、DispId 等も――を、適切に指定する必要がでてくるかと思います。

0
引用返信 編集キー/
■6640 / inTopicNo.5)  Re[4]: C# から VB6.0のDLLのメッソドを起動
□投稿者/ mizuki 二等兵(3回)-(2006/09/20(Wed) 16:55:13)

分類:[C#] 

ありがとうございました。

上司と話をして、妥協点を見出してみます。
お手数かけました。

No6632に返信(魔界の仮面弁士さんの記事)
> 2006/09/20(Wed) 15:24:14 編集(投稿者)
>
> 本当に、DLL 側がそのような実装になっているのでしょうか?
>
> サンプルコードだからかも知れませんが、HogeMethed が ByVal ではなく
> ByRef になっている理由が不明瞭に感じます。それに、LogIF で、vbErrorlog を
> パブリックフィールドとして公開している理由もよくわかりませんでした。
>

ソースを送付出来るなら、見て頂きたいのですが、
セキュリティの問題もありますので、送付する事は出来ませんが、
かなり、雑な仕組みになってます。
中身を見ると、びっくりすると思います。

>
>> *LogIF.cls の中身
>> *vbErrorlog.cls の中身
>
> VB6 側で生成されたこれらのクラスと、
>
>> public class LogIF
>> public class vbError
>
> .NET2.0 側で生成されたこれらのクラスの間には、互換性がありません。
> 単に、その内容が酷似しているというだけで、実際には別物です。
違う物になると思ったのですが、確証を持っていなかったので。

> もしもその ActiveX DLL を参照設定しているのであれば、わざわざ LogIF/vbError の
> クラスを C# 側で再定義せずとも、それらを C# 側で利用できるかと思います。
> まずはそれを試してください。(VB6側の、各クラスのInstancingプロパティ次第ですが)
>
上記でも触れましたが、プロジェクトにクラスがLogIF/vbErrorのクラスが
参照されていないので・・、Object型なのでLogIF/vbErrorの実態が無くても
コンパイルは通る為・・・・・・(なんかすごく怖いけど・・)

>
> そしてもし、COMクラスと互換性のあるマネージクラスを再定義せねばならないのだと
> すれば、それらのクラスやメンバに、元のCOMクラスとバイナリ互換性を持たせる
> ために、ComVisible を始めとする幾つかの属性――場合によっては、InterfaceTypeや
> Guid、DispId 等も――を、適切に指定する必要がでてくるかと思います。
このあたりの事は、今回C#(.Net)を初めて使ったので、勉強不足です。
もう少し、勉強してわからなくなったら、また投稿させていただきます。




解決済み
引用返信 編集キー/
■6650 / inTopicNo.6)  Re[5]: C# から VB6.0のDLLのメッソドを起動
□投稿者/ 魔界の仮面弁士 中尉(144回)-(2006/09/20(Wed) 23:39:16)

分類:[C#] 

2006/09/21(Thu) 13:08:55 編集(投稿者)

> 上記でも触れましたが、プロジェクトにクラスがLogIF/vbErrorのクラスが
> 参照されていないので・・

参照していないのであれば、参照してみては如何でしょう。

もちろん、参照せずに C# 側で COM クラスを定義する事は可能ですが、もしも
C# で COM クラスを作るだけの知識が不足しているのであれば、タイプライブラリ
もしくは VB6 などを使ってそれらの COM クラスを作成し、それを C# から
参照設定してやれば、C# 側で class LogIF {} や interface _LogIF {} などを
定義する必要がなくなりますよ。


>>ComVisible を始めとする幾つかの属性――場合によっては、InterfaceTypeや
>>Guid、DispId 等も――を、適切に指定する必要がでてくるかと思います。
> このあたりの事は、今回C#(.Net)を初めて使ったので、勉強不足です。

.NET 製のクラスを COM/ActiveX コンポーネントとして公開するのであれば、
最低限、[ComVisible(true)] の属性指定が必要となってきます。
今回、VB6側はレイトバインドですので、おそらく、ComVisible の指定だけで
いけるかと思います。試してみてください。


なお、特に指定しなければ、ComVisible は true として処理されるのですが、
C# の場合、AssemblyInfo.cs によって、 [assembly: ComVisible(false)] と
指定されているため、標準では VB6 からは使えない、COM 非公開のクラスとして
コンパイルされてしまうのです。

なので、このアセンブリ情報を true に書き換えるか、もしくは個々のクラスに
対して、[ComVisible(true)] を指定して、その設定を変更する必要がでてきます。


> もう少し、勉強してわからなくなったら、また投稿させていただきます。

VB6 との連携に関しては、下記のサイトが参考になるでしょう。

[.NETコンポーネントをVB6から使用するための方法]
http://www.sev.or.jp/ijupiter/world/dc_interrop/dotnet_com_interrop.html


また、(今回は不要とは思いますが).NET と COM のより深い部分に関して
知りたければ、下記のようなサイトを見ておくのも良いかと思います。

[虚無僧 - COM総合研究所]
http://www5.plala.or.jp/atata/

解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -