• 締切済み

VBA,ASPなどから呼び出せるDLLの作成

DLLを作成したいです。 開発環境 OS:WindowsXP HOME SP2 IDE:Visual C++ 2005 作成したいのはBASP21 DLL(http://www.hi-ho.ne.jp/babaq/basp21.html)のようなVBA、VBScriptから呼び出せるDLLです。 以下のように作成しました。 1 新規プロジェクト>ATLプロジェクト(プロジェクト名:dlltest)   (ダイナミックリンクライブラリ・非属性、デフォルト) 2 プロジェクト>クラスの追加>ATLシンプルオブジェクト(クラス名:cl1、オプションはデフォルト) 3 作成されたインターフェースIcl1を右クリックしてメソッドを追加   メソッド名:mtest1 質問したいのはこのメソッドで値を呼び出し側に返す方法です。 COMの仕様で返り値はHRESULTと聞きました。 LONG型の引数を受け取って2倍した値を返すメソッドみたいな簡単な サンプルの記述方法を教えてください。お願いします。

みんなの回答

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.3

COMについては、次のサイトが参考になると思います。 http://msdn.microsoft.com/en-us/library/aa139694.aspx > HRESULT型の正体はlong型なので、関数の戻り値をHRESULT型で定義すれば、longの値(0x00000000~0xffffffffの値)を返す事が出来る。 COM の仕様とは使い方が、違うので、そのやり方では、VBAやVBScriptからは呼び出せないかと思いますよ。 ActiveX では、戻り値の型をメソッドの最後のパラメタをポインタとして戻すって言うのは、 MSDNのリファレンスの通りです。 MIDLでインターフェイスを定義しておくと、VBAやVBScriptから呼び出した時に、 最後のパラメタを戻り値として使用できます。 呼び出し元が、C/C++の場合は、VBAやVBScriptから呼び出す時と、パラメタの使い方が違う事に注意。

vijareal
質問者

お礼

何度も回答をありがとうございます。 > MIDLでインターフェイスを定義 するには具体的にどうするのでしょうか? 参考ページを見て理解すべきとは思いますが、 できれば教えていただきたいです。

  • chie65535
  • ベストアンサー率43% (8526/19383)
回答No.2

HRESULT型の正体はlong型なので、関数の戻り値をHRESULT型で定義すれば、longの値(0x00000000~0xffffffffの値)を返す事が出来る。 A.No1の回答を借りれば、     [id(1), helpstring("mtest1")]       HRESULT mtest1(             [in] long a); ---------------------------------------------------------------------- ソースは、 HRESULT __stdcall CDllTest::mtest1(long a) {   return a * 2; } で良い筈。 A.No1で、関数の戻り値をHRESULT型にしておきながら「return 0;」で0しか返してないのが意味不明過ぎる。 せっかく戻り値をHRESULT型にして、0x00000000~0xffffffffまでの値を返せるようにしたんなら、答えの返却場所を2番目の引数に与えたりしないで、素直に「return 答え;」ってやれば良いじゃないか。 A.No1の回答者さんは、何が言いたかったんだろう?理解に苦しむ。

vijareal
質問者

お礼

ご回答ありがとうございます。 chie65535さんの記述通りに  return a*2: としましたが、VBAから値を受け取れませんでした。 難しいです。

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

インターフェイスの定義を次の様にして、     [id(1), helpstring("mtest1")]       HRESULT mtest1(             [in] long a,             [out, retval] long*); ---------------------------------------------------------------------- ソースは、 HRESULT __stdcall CDllTest::mtest1(long a, long* pRetValue) {   if (pRetValue)   {     *pRetValue = a * 2;   }   return 0; } かな。 ---------------------------------------------------------------------- テストしていませんので、参考までにしてください。

vijareal
質問者

お礼

回答ありがとうございます。 上記コードで作成したmtest1メソッドの呼び出し側の記述はどうなるのですか?単純に set obj = CreateObject("dlltest.cl1") i = obj.mtest1(100) でiは200を受け取れなかったです。 [out,retval]long* という引き数を使う方法ではなく返り値を呼び出し側に渡す方法は ないでしょうか? 質問にあげたBASP21 DLLのメソッドのようにしたいのですが・・・

関連するQ&A

  • AccessVBAからC言語のDLLの呼び出し方

    初心者です。はじめまして お世話になります。 概要:C言語で作成したDLLをVBAで呼び出す。 タイトルの通り、C言語で作成したDLLをVBAで呼び出したいのですが、うまく 呼び出すことができず、「エラー番号:49 DLLを正しく呼び出せません。」 というエラーが返ってきてしまいます。 DLLの作成手順もしくはDLLの呼び出し方でおかしな所があればご指摘頂けない でしょうか? C言語のDLL、作成手順は以下の通りです。 DLL作成環境:Visual C++ 6.0 DLL作成手順----------------------------------------- (1)プロジェクトをDLL用に作る  新規作成→プロジェクト→Win32 Dynamic-Link Library→空のDLLプロジェ クト (2)ファイル追加  ソースファイル+すべてのヘッダファイルを追加 (3)DLLを出力対象の関数に「_declspec(dllexport)」をつける 例)------------------------------------- _declspec(dllexport) short dlltest (char *str1, char *str2) --------------------------------------- (4)char を unsigned char へ変換する(/J コンパイルオプション) (5)プロジェクトをデバッグモードからリリースモードに切り替える (6)ビルド実行 (7)「Release」配下に.dllとlibができる。 -作成手順完----------------------------------------------------- 実際のVBAのDLLの呼び出しは以下の通り行っています。 -AccessVBAにてDLLの宣言及び、呼び出し------------------- '呼び出し宣言 Public Declare Function dlltest _ Lib "C:\Project\Dlltest\Release\dlltest.dll" _ (ByVal st1 As String, _ ByVal st2 As String) As Integer 'DLL呼び出し KEKKA = dlltest(string1, string2) -呼び出し完------------------------------------------------ これで実行するとエラーが返されていまいます。 なにぶん、初心者で今回初めてVBAでのプログラミングを行っているので観点 の抜けなどが多分にあると思われます。 どんな小さなことでもご指摘頂けないでしょうか? 宜しくお願い致します。

  • VC6でDLL(COM+)作成中にエラーが出ました。

    VC6でATL COM AppWizardでDLLを作成しています。 インターフェースメソッドを追加したところ、 (1)の場合はうまくいきましたが、(2)の場合は、エラーと警告が2つ出ました。 理屈がわかっていないので対処方法がわからないのですが、何が原因なのでしょうか? やりたいことは、戻り値1つでなく、3つの戻り値が必要で、 引数4つのうち、最初は関数へ計算の元となる文字列を送り、残りの3つはint型ポインタを与えて、関数内で結果をセットし、呼び出し元でも使えるようにしたいので、このようにしました。通常のC?ではうまくいっていました。 あと読んだ方が良い書籍も探しています。 COM+?について詳しい方、教えてください。 ※COM+というのはVB2005やC#でも健在なのでしょうか? (1) 戻り値のタイプ: HRESULT メソッド名: Test1 パラメータ: なし (2) 戻り値のタイプ: HRESULT メソッド名: Test2 パラメータ: [in] char* a, [in,out] int* b, [in,out] int* c, [in,out] int* d →※ここが間違い? ===== エラー内容 ===== error C2259: 'CComObject<class CTest>' : 抽象クラスあるいは構造体のオブジェクトが宣言されています。 クラス テンプレートのメンバ関数 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CTest> >::CreateInstance(void *,const struct _GUID &,void ** )' のコンパイル中 warning C4259: 'long __stdcall ITest::Test2(unsigned char *,int *,int *,int *)' : 純粋仮想関数は定義されていません。 'Test2' の宣言を確認してください。 クラス テンプレートのメンバ関数 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CTest> >::CreateInstance(void *,const struct _GUID &,void ** )' のコンパイル中 error C2259: 'CComObject<class CTest>' : 抽象クラスあるいは構造体のオブジェクトが宣言されています。 クラス テンプレートのメンバ関数 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CTest> >::CreateInstance(void *,const struct _GUID &,void ** )' のコンパイル中 warning C4259: 'long __stdcall ITest::Test2(unsigned char *,int *,int *,int *)' : 純粋仮想関数は定義されていません。 'Test2' の宣言を確認してください。 クラス テンプレートのメンバ関数 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CTest> >::CreateInstance(void *,const struct _GUID &,void ** )' のコンパイル中

  • VC++ ATLコントロールのインスタンス

    VC++2008で、ATLコントロールクラスを追加し、 そのクラスにPublicメソッドを追加しました。 (IXxxxインタフェースを右クリック→追加→メソッドの追加) この追加したメソッドを、同じプロジェクト内のMFCクラスから 呼びたい(実行したい)と思っています。 ただ、ATLコントロールクラスがインスタンスできない為、 呼ぶことができません。 (「抽象クラス型のオブジェクトは使用できません」のエラーが出る) MFCクラスのメソッド→ATLコントロールクラスのメソッドを実行 というのは、不可能なのでしょうか? ご存知の方がおられましたら情報をください。 宜しくお願いします。

  • 作成したDLLをATL_COM_APPWIZARDで利用する方法について

    VC6++のWin32 Dynamic Link LibraryでDLLを作成しました。 DLLはできたのですが、これを利用する方法がわかりません。 ATL COM AppWizardで作成するアプリからDLLのクラスを使いたいのですが、どのようにすれば使えるのでしょうか? 最初のDLL側は class Test{ Test(){ ShowMessageBox(NULL, "最初のDLL", "呼ばれました", MB_OK); } }; というクラスです。 ATL COM Appwizardでは、 どのように記述すれば、DLLのクラスを利用することができるのでしょうか?

  • dll作成

    Visual studio2012利用し、 Win32プロジェクト から DLLを選んで、テンプレートに、関数を記入。ヘッダファイルを追加し、そこに関数の宣言を書いた。 ビルドすると、Debugフォルダに.dllは作成され、exeファイルが作成されない。 デバックなしで開始するとdllは開始できません。とメッセージがでます。 作成されたdllファイルの開始の仕方を、教えてください。

  • visualstudioでc#のdllができない

    visualstudio2010を使用しています。 dllの作成をしたいのですが、なぜか作られません。 どこに手順を書きますのでどこに間違いがあるか教えてください。 (1)作成したプロジェクトを開く (2)ファイルー新しいプロジェクトを選択 (3)クラスライブラリを選択 (4)ソリューション(S):ソリューションに追加を選択ーOKボタン (5)DLLの中を書く (6)参照設定を選択する (7)ソリューションのプロパティのビルドでフォルダを指定する。 (8)ビルドする(もちろん通る) しかし、DLLはどこにも見当たらない。 検索しても、クラスライブラリを選択すれば自動的にできると書いてあるので、困り果てています 機能はMEFを使用し、僕ではない人が作ったDLLがすでに追加されており、僕もDLLを追加したいのですが、なぜかDLLが作成されません。 詳しいかたよろしくおねがいします。

  • DLL作成について

    DLL作成の機会がいろいろ調べているのですが、教えていただきたいことがあります。 1.インポートライブラリについて  Windowsで暗黙的リンクでDLLをリンクする場合、  インポートライブラリを利用するようですが、  これは、DLL内のポインタと関数名を紐付けるような  役割だと想定しています。  仮に関数等ヘッダーで公開されている部分以外で  DLLを更新した場合、インポートライブラリも  再リンクするような場面があるのでしょうか。  特に再リンクしなくてもDLLの更新が反映されたので・・ 2.DLLのクラスの継承について  DLL内に作成したクラスを継承することは不可能ですかね。  DLLが更新された場合、インスタンスのイメージが違うため  newやdeleteの処理で当初リンクしたインスタンスのイメージで  行いますよね。

  • COMについて

    ATL COM AppWizardを使用し、簡単なメソッドを追加し、DLLは作成できたのですが、ASPから実行した後、サーバー上にある作成したDLLを削除できません。 メモリーを開放するプログラムを追加する必要があるのでしょうか?それとも他に何か方法があるのでしょうか?

  • DLLの作成でで

    DLLの作成でで extern "C" int test(void) { int a; a=2; return a; } test の前のintは返す値の型なのでしょうか? もし文字を返す場合はcharでいいのでしょうか? また複数の値を返す場合は別に追加しなければいけないのでしょうか?よろしくお願いいたします。 初心者なので説明が下手ですがよろしくお願いいたします。

  • C#でのDLL

    OS  :WindowsXP Pro SP1 開発環境:VisualStudio .NET 2003 開発言語:C# 開発形態:Windowsアプリケーション 開発初心者です。よろしくお願い致します。 テキストファイルを読み込んで、その中にある文字列を3つほど返却値として返すDLLを作成したいと思っています。 新規にクラスライブラリのテンプレートでプロジェクトを作成し、プロジェクトメニューからコンポーネントの追加をしました。 質問事項 1.まず、DLLを作成する手順として、上記の方法でよろしいのでしょうか? 2.ファイルからテキストを取得するところまではできるのですが、それを返却値として、呼び出し元の別プロジェクトへは、どうすればよいのでしょうか? どなたか、ご教授お願い致します。