C#で作成したdllをVBScriptで利用する際のマーシャリングの問題

このQ&Aのポイント
  • C#で作成したdllをVBScriptで使用する際には、マーシャリングの問題が発生します。
  • 質問者はClassicASPでWebアプリケーションを開発しており、C#で作成したdllをCOM登録して利用しようとしていますが、データの受け渡し部分で問題が発生しています。
  • 特に困っているのは、C#側の関数の戻り値として独自のクラス(構造体)の配列を返したいということです。
回答を見る
  • ベストアンサー

C#で作成したdllをVBScriptで使うときのマーシャリングの問題

お世話になります。 現在ClassicASPでWebアプリケーションを開発しているのですが、 その時にC#で作成したdllを使用したいと思い、 COM登録をしてASP側ではServer.CreateObjectで使用しようとしています。 しかし、データの受け渡し部分でずっとつまづいています。 やりたいことは、C#側の関数の戻り値で独自のクラス(構造体)の配列を戻したいのです。 以下サンプルコードです。 ASP側 <%@ Language=VBScript%> <% Response.ContentType = "text/html" Dim testObject set testObject = Server.CreateObject("TestObject") list = testObject.getList() Response.Write(TypeName(list)) ' ここで、[VBScript でサポートされていないオートメーションが変数で使用されています]エラー %> C#側 [StructLayout(LayoutKind.Sequential)] public struct TestData { [MarshalAs(UnmanagedType.BStr, SizeConst = 1024)] public String title; } public interface ITestObject { TestData[] getList(); } public class TestObject : ITestObject { public TestData[] getList() { TestData[2] result; result[0].title = "1"; result[1].title = "2"; return result; } } あとどういった処理が足りないのでしょうか? やりたいことは、構造体配列をASP側に渡したいだけです。 本当に困っています、なにとぞ宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

VBScriptでは変数に型がありません。当然、構造体もありません。 Variant型で、形式が配列であるデータを返すようにしないと成功 しません。 また、要素が構造体なので、これ自体を別途、クラスとして登録 するか、文字列の配列として扱うようにする必要があります。 「VB用と同じ」と考えて設計したのであれば、全体の設計を見直す ことを薦めます。

ayumi_g
質問者

お礼

度々すみません、解決しました! C#側でObjectの配列を返すようにし、その中にClassにしたTestDataを入れるようにしたら無事ASP側で受け取ることが出来るようになりました。 Variant型しかないのでObject配列で受け取る必要があったのですね。 本当にありがとうございました。 以下解決コードです。 ASP側 <%@ Language=VBScript%> <% Response.ContentType = "text/html" Dim testObject set testObject = Server.CreateObject("TestObject") list = testObject.getList() Response.Write(TypeName(list)) %> C#側 public class TestData { public String title; } public interface ITestObject { Object[] getList(); } public class TestObject : ITestObject { public Object[] getList() { Object[] result = new Object[2]; TestData data; TestData[0] = data = new TestData(); data.title = "1"; TestData[1] = data = new TestData(); data.title = "2"; return result; } } 本当にありがとうございました。

ayumi_g
質問者

補足

お返事ありがとうございます! こんなにも直ぐにご回答いただけるとは思っていませんでした。ありがとうございます。 >VBScriptでは変数に型がありません。当然、構造体もありません。 >Variant型で、形式が配列であるデータを返すようにしないと成功 >しません。 なるほど、、つまりObject配列を返して、その中にはプリミティブなデータ型しか入れることはできないという認識でよいのでしょうか? >これ自体を別途、クラスとして登録 >するか、文字列の配列として扱うようにする必要があります。 文字列の配列にするのは最終手段と思っていたのですが、 別途クラスとして登録というのはC#とVBScriptどちらでクラスを作成するのでしょうか? >「VB用と同じ」と考えて設計したのであれば、全体の設計を見直す >ことを薦めます。 実験的にエクセルVBAで試していて、そちらで出来たのでVBScriptでも大丈夫だろうと楽観していました。 見直しをしようと思います、ありがとうございます。

関連するQ&A

  • VBScript で動的配列

    VBScript で動的配列 VB ではなく、VBScript で動的配列を実装したクラスはないでしょうか (自分で実装するのではなく、CreateObject() とかですぐにインスタンス化できるもの)。 私は C++ の STL で vector/list/map を多用していたのですが、VBScript で vector/list の様に使えるクラスを探しています (map は VBScript の Dictionary でだいたい似たようなことができる)。 条件としては、 (1) メモリの許す限り、要素をパカパカ追加していくことができる。 (2) 要素をすべて列挙できる。 (3) 要素を追加した順に列挙できる。 (4) 追加した順に要素を削除していくことができる (FIFO)。 (5) 追加した順とは逆順に要素を削除していくことができる (FILO)。 (6) 整数インデックスでランダムアクセスできる。 の様なものを探しています。(3)~(6) はオプションの条件なのですべて満たしている必要はありません。 「ReDim や Dictionary を使って自分で実装する必要がある」という意見の方は簡潔にそう記してください。実装方法は必要はありません。 なるべく、独自のクラスを定義することなく、そのまま使えるものがいいです。 ご存じの方、いましたら、よろしくお願いします。

  • コマンドプロンプトの出力をVBScript内の変数に代入する

    VBScriptからコマンドプロンプトのver | findstr 5.1を実行し、その出力結果をVBScript内の変数に代入したいのですが、どうすればいいでしょうか? Dim WShell Dim result Set WShell = WScript.CreateObject("WScript.Shell") WShell.Run "cmd /c (ver | findstr XP > " & result & ")" MsgBox result とやってもresultには何も入っていませんでした。

  • C++/CLIとC#の連携について

    いつも拝見させていただいております。 現在、C++/CLIとC#にて連携を行っているのですが、C++/CLIで作成したクラス配列 がC#側でどのようにすれば受け取れるのか方法がわかりません。 C++/CLIで作成しているクラス配列はSystem::Collections::Generic::Listを使用 して配列化しています。 下記がC++/CLIのソースになります。 List<testClass>^% testClass::GetList() { List<testClass>^ lpTestClassList = gcnew List<testClass>(); testClass^ lpTestClass; lpTestClass = gcnew testClass(); lpTestClassList->Add(lpWatchServiceMasterInfoWrapper); return lpTestClassList; } これをC#側で使用しようとすると下記エラーが発生します。  「この言語によってサポートされていません」 C++/CLI⇒C#間の連携ではListクラスを使用することは不可能なのでしょうか? クラスを配列にして引き渡したいだけなので、他の方法等含めて何か参考になることがありましたら ご教授ください。 よろしくお願い致します。 開発環境  C++/CLI ⇒ DLL(ネイティブなコードを参照するためのラッパー用DLL)  C# ⇒ アプリケーション

  • VBScriptでファイル保存先のデフォルト設定

    こんにちわ。 ASP(VBScript)で、CSV形式のデータを出力する処理を作成しています。 ヘッダー部に Response.ContentType = "text/csv" Response.AddHeader "Content-Disposition","filename=" & CSVFileName と書いて、該当のページを開いたら、ファイル保存のダイ アログを表示するようにしているのですが、ファイル保存 先は、デフォルトではデスクトップになっています。 これを、Cドライブあたりにしたいのですが、VBScriptで その辺の制御はできるのでしょうか?

  • c# でList<T>と似たものを作りたい

    c#初心者です。 c#のList<T>などのコレクションのように動的かつ高速に配列の容量を変更できるクラスを作りたいのですが、Listの構造すら分からないわ、普通の配列で色々やってみて上手くいかないわで困っています。 要はListやDictionaryがもつAddメソッドの基本的な内容が分かれば良いのですが、どなたか教えていただけないでしょうか?

  • VC#からdll関数を使う

    c#(vs2003)から、c++で書かれたdllの中に含まれる関数を読み込む部分を書いています。この関数は以下のように定義 され、構造体のポインタを返り値として返します。 SENSOR* GetSensor(); SENSOR構造体はdllの中では以下のように定義されています。 typedef struct{   int type; unsigned short param; char name[64]; DWORD con_pos; } SENSOR; これをc#のコードの中で読み込むため、c#のクラスの中で、以下のように再定義しました。 [StructLayout(LayoutKind.Sequential)] public struct SENSOR {   public int type;   public ushort param;   public string name;   public uint con_pos; } 後にc#のコードの中に、dllの中の関数を呼び出す定義を以下のように書きました。 [DllImport("sensor.dll"); public static extern SENSOR* GetSensor(); ここで SENSOR* sensor = GetSensor(); といった感じでdllをの関数を使って値を取得するようにしたのですが、実行すると 「return value をマーシャル できません : ポインタはマーシャルされた構造体を参照できません。」 といったエラーが出ます。いろいろと調べたのですが解決方法がわかりません。アドバイスをいただけたら幸いです。

  • C++/C#間での構造体の引き渡し方法に関して

    現在、C++で作成したクラスを、 C#から呼び出し実行しようとしております。 引数として、構造体を利用したいので、 C++側、C#側でそれぞれ下記のように 構造体を定義しました。 【C++】 typedef struct _Msg { ULONG Code; ULONG sessionId; }Msg; 【C#】 [StructLayout(LayoutKind.Sequential)] public struct Msg { public uint Code; public uint sessionId; } そして、下記のようにC++側で定義したクラスを C#側で呼び出そうとしたのですが、 「Msg*から_Msg*に変換できません」という コンパイルエラーが発生してしまいました。 構造体の定義は同じものになっていると思うのですが、 この原因は何だと考えられるでしょうか。 よろしくお願いいたします。 【C++】 ULONG Wrap::API( Msg* sample_Msg ) { return 1; } 【C#】 Msg sample_msg; Wrap.API(&sample_msg);

  • Access2003からシンプルにファイルを添付してメール送信したいと

    Access2003からシンプルにファイルを添付してメール送信したいと考えています。 こちら(http://www.site-cooler.com/kwl/asp/19.htm)を参考に、BASP21というコンポーネントを利用してACCESS上のフォームにボタンを用意してコードビルダで下記のように記述してみましたが、「コンパイルエラー:構文エラー」と表示されました。 どのように改善すれば良いのでしょうか。 ACCESS初心者の為、すみませんがご教示お願いします。 --------------------------------------------------------------------------- Private Sub コマンド0_Click() Set bobj = Server.CreateObject("basp21") bobj.SendMail() <%@ LANGUAGE = VBSCRIPT %> <% Dim strServer 'SMTPサーバ Dim strTo '宛先 Dim strFrom '送信元 Dim strSub 'メール標題 Dim strBody 'メール本文 Dim strFile '添付ファイル Dim result '戻り値 strServer = "smtp.xxxx.co.jp" strTo = "xxxx@xxxx.co.jp" strFrom = "xxxx@xxxx.co.jp" strSub = "件名" strBody = "本文です。" & vbCrLf & "本文終了" strFile = "c:\text.txt" Set bobj = Server.CreateObject("basp21") result = bobj.SendMail(strServer, strTo, strFrom, strSub, strBody, strFile) If result <> "" Then Response.Write ("メール送信エラー :" & result) Response.End End If Response.Write ("メール送信完了") %> If result <> "" Then Response.Write ("メール送信エラー :" & result) Response.End End If End Sub ---------------------------------------------------------------------------

  • FLASHからアプリケーションの呼出し

    「問合せ」用のページを作成し、メール送信用に作成してもらったプログラムを起動させたいと思っています。 sendmail.aspと言うvbscriptで記述されたプログラムをcall出来るのですが、パラメーターが渡されません。 getURL("./sendmail.asp?parm1="+result1 + "&parm2="+result2 + "&parm3="+result3 + "&parm4="+result4) ; サーバーを通さない状態で動かして見ると、ブラウザが立ち上がりアドレスバーには 「c:\・・・・・\sendmail.asp」 と表示されるのですが、その後にパラメーターが付いていません。この時点でパラメーターが付いていないと何も始まらないと思うのです。 お知恵を拝借したく、宜しく御願いします。

    • ベストアンサー
    • Flash
  • C言語で使うことの出来る配列のLIB

    C言語から使うことの出来るSTLのコンテナクラスのようなものはありますでしょうか? 配列の追加、削除、検索、更新を高速で処理したいので(LIST構造)、汎用的に使えるLIBのようなものがあれば教えていただきたいです。

専門家に質問してみよう