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

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

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

Re[3]: VbScriptからCOM+(C#)へのオブジェクト渡し


(過去ログ 53 を表示中)

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

■29564 / inTopicNo.1)  VbScriptからCOM+(C#)へのオブジェクト渡し
  
□投稿者/ iSyouta (1回)-(2008/12/10(Wed) 17:58:22)

分類:[C#] 

2008/12/10(Wed) 18:06:15 編集(投稿者)
2008/12/10(Wed) 18:06:06 編集(投稿者)

こんにちは。
初めて書かさせて頂きます。
とても困りましたのでご教授願えればと思います。

今,ASP(VBScript)からC#で作成したCOMにオブジェクト(プロパティクラス)を渡し(参照渡し)、COM内で値を編集し呼出元で、編集された値を表示するものを作っているのですが、下記のエラーがでてしまいます。

エラー タイプ
Microsoft VBScript 実行時エラー (0x800A0005)
プロシージャの呼び出し、または引数が不正です。: 'mtdReturn'
/ASP/TOP/include/test.inc, line 24

以下がソースになります。
[ASP/VBScript](エラー処理など細かい処理は省いてあります。)

<%

Dim objCom 'COMオブジェクト
Dim objComDataBean   'DataBeanオブジェクト

Set objComDataBean = Server.CreateObject("ClassLibrary.property_DataBean")

objComDataBean.intNum1 = 1
objComDataBean.intNum2 = 3
objComDataBean.intNum3 = 0

Set objCom = CreateObject("ClassLibrary.Method")

Call objCom.mtdReturn(objComDataBean)←ーーーーーーーー

Set objCom = Nothing
Set objComDataBean = Nothing
%>
Response.Write(objcomDataBean.intNum3)
************************************************************************
[COM(C#)]
using System;
using System.EnterpriseServices;
using System.Runtime.InteropServices;

namespace ClassLibrary
{
/// <summary>
/// プロパティクラス
/// </summary>
public class property_DataBean
{
private int mintNUM1;
private int mintNUM2;

public property_DataBean()
{
mintNUM1 = 0;
mintNUM2 = 0;
}

public int intNUM1
{
get{return mintNUM1;}
set{this.mintNUM1 = value;}
}

public int intNUM2
{
get{return mintNUM2;}
set{this.mintNUM2 = value;}
}
public int intNUM3
{
get{return mintNUM3;}
set{this.mintNUM3 = value;}
}
}

/// <summary>
/// 処理クラス
/// </summary>
public class Method
{
public Method()
{
}

public int mtdReturn( property_DataBean prpDb)
{
prpDb.intNUM3 = prpDb.intNUM1 + prpDb.intNUM2;
}

}
}

で、COM内のmtdReturnの引数を「object prpdb」に変えれば通るのですが、
それだと、ASP側で代入した値が使用できずで困っています。
ここに書くまでにたくさん調べまして有力な情報が見つけれず、もしくは自分の理解度が足りていないのかもしれませんが、ヒントでも教えていただけると助かります。宜しくお願い致します。


引用返信 編集キー/
■29577 / inTopicNo.2)  Re[1]: VbScriptからCOM+(C#)へのオブジェクト渡し
□投稿者/ 魔界の仮面弁士 (943回)-(2008/12/10(Wed) 20:47:58)
2008/12/10(Wed) 21:57:47 編集(投稿者)
No29564 (iSyouta さん) に返信
> 下記のエラーがでてしまいます。
とりあえず修正案。

★案1: C# 側は変更せず、VBScript 側を値渡しにする ★
'Call objCom.mtdReturn(objComDataBean)
Call objCom.mtdReturn((objComDataBean))


★案2: VBScript 側は変更せず、C# 側で MarshalAs(IDispatch) 属性を付加 ★
// public int mtdReturn( property_DataBean prpDb)
public int mtdReturn([MarshalAs(UnmanagedType.IDispatch)] property_DataBean prpDb)


> で、COM内のmtdReturnの引数を「object prpdb」に変えれば通るのですが、
> それだと、ASP側で代入した値が使用できずで困っています。

★案3: object で受け、それを C# 側でキャストする★

public void mtdReturn(object /* property_DataBean */ prpDb)
{
    /*
    if (prpDb == null)
    {
        throw new ArgumentNullException();
    }
    else if (!(prpDb is property_DataBean))
    {
        throw new InvalidOleVariantTypeException();
    }
    */
    property_DataBean p = (property_DataBean)prpDb;
    p.intNUM3 = p.intNUM1 + p.intNUM2;
}



> 以下がソースになります。
以下、細かいツッコミ。


> 	Set objComDataBean = Server.CreateObject("ClassLibrary.property_DataBean")
> 	Set objCom 	= CreateObject("ClassLibrary.Method")
後者の記述は利用しないでください。
http://support.microsoft.com/kb/414599/ja

> %>
> Response.Write(objcomDataBean.intNum3)
スクリプトが、<%〜%>の外に書かれています。

それと上記の記述だと、
  Call Response.Write((objcomDataBean.intNum3))
という意味になってしまいます。この場合は
  Response.Write objcomDataBean.intNum3
あるいは
  Call Response.Write(objcomDataBean.intNum3)
と記述してください。


> 		private int mintNUM1;
> 		private int mintNUM2;
> 
mintNUM3 が抜けています。


> 		public int mtdReturn( property_DataBean prpDb)
> 		{
> 			 prpDb.intNUM3 = prpDb.intNUM1 + prpDb.intNUM2;
> 		}
return がありません。または、戻り値を void にすべきかと。

引用返信 編集キー/
■29592 / inTopicNo.3)  Re[2]: VbScriptからCOM+(C#)へのオブジェクト渡し
□投稿者/ iSyouta (2回)-(2008/12/11(Thu) 10:42:15)
おはようございます!!

魔界の仮面弁士様
ご助言ありがとうございます!!
早速頂いた意見から案3が一番近いのかと思いますので試してみます!!
他の案1、2も勉強のために試してみたいと思います★
試してみてフィードバック後に解決に致します。

ちなみに今回載せたソースはもともとASP/VBScriptで書かれたものを今回、COM+/C#に移行するものなのですが、これからの事を考えると、
C#側をいじった方が良いのか、ASP/VBScript側なのか迷います。

> ★案1: C# 側は変更せず、VBScript 側を値渡しにする ★
> 'Call objCom.mtdReturn(objComDataBean)
> Call objCom.mtdReturn((objComDataBean))
2重括弧で値渡しとなるんですね。勉強不足でした。。。。

>>以下がソースになります。
> 以下、細かいツッコミ。

細かいツッコミでも助かります!!!!!
すいません。。載せるようにソースを適当にしてしまったらあちこちで
ボロがでてますね。。
でもそのおかがで「Server.CreateObject」と「CreateObject」の違いを知ることができました。あるASP入門者サイトで見た時は「Server.」がなかったもので.....

> 後者の記述は利用しないでください。
> http://support.microsoft.com/kb/414599/ja

> それと上記の記述だと、
Call Response.Write((objcomDataBean.intNum3))
> という意味になってしまいます。この場合は.....

処理の意味が変わってしまうという事でしょうか??
処理は変わらないとしても2重括弧はおかしいですね。
以後気をつけます!!!!


引用返信 編集キー/
■29604 / inTopicNo.4)  Re[3]: VbScriptからCOM+(C#)へのオブジェクト渡し
□投稿者/ 魔界の仮面弁士 (945回)-(2008/12/11(Thu) 13:17:22)
No29592 (iSyouta さん) に返信
>>'Call objCom.mtdReturn(objComDataBean)
>>Call objCom.mtdReturn((objComDataBean))
> 2重括弧で値渡しとなるんですね。勉強不足でした。。。。
# 2 重括弧と表現してしまうと語弊があるかも。

括弧を付けるのは、「変数」を「式」に変えるためです。

たとえば、整数を参照渡しするメソッドがあったとして、
 Foo.ByRefMethod(a)
によって、変数 a の中身が書き換わる事はあっても、
 Foo.ByRefMethod(a + 1)
や
 Foo.ByRefMethod(123)
と指定した場合は、メソッド側で引数を書き換えたとしても、
数式 a + 1 や、リテラル 123 まで書き換わるわけではありません。

動作的には、値渡しというよりは C# 的でいうところの
 Foo.Method(ref x);
というコードを、
 work = (x);
 Foo.Method(ref work);
 // x = work;  //書き戻さない…
に修正した状態に近い状態になります。


おまけ。
http://support.microsoft.com/kb/197956/ja
http://support.microsoft.com/kb/243548/ja


>>> Response.Write(objcomDataBean.intNum3)
>>それと上記の記述だと、
> Call Response.Write((objcomDataBean.intNum3))
>>という意味になってしまいます。この場合は.....
> 処理の意味が変わってしまうという事でしょうか??

元コードにあった括弧は、メソッド呼び出しの括弧を意味しているわけではありません。
非.NET な Visual Basic 系言語においては、
 『メソッドの呼び出しに括弧は使わない。括弧を付けたいなら Call を併用。』
という仕様になっています。

特に、複数の引数を持つメソッドの呼び出しにおいては、
 Foo.Method("aaa", "bbb", "ccc")
という記述にすると、そもそも文法違反となりますので、
 Foo.Method "aaa", "bbb", "ccc"
もしくは
 Call Foo.Method("aaa", "bbb", "ccc")
と記述する事が求められます。

今回は引数の数が 1 個だけだったので、それが「式」としての括弧として
扱われるため、文法的には 一応 通ってしまっていたというだけです。

ちなみに引数 0 個の場合は、というと、
 Call Foo     '…VB6 = ○, VBS = ○ 'これでも一応OK
 Call Foo()   '…VB6 = ◎, VBS = ◎ 'これが正しい
 Foo          '…VB6 = ◎, VBS = ◎ 'これが正しい
 Foo()        '…VB6 = ×, VBS = ○
のように、VB6 と VBS とで文法判定が微妙に異なっていたりします。

引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -