• ベストアンサー

COMプログラミング教えてください。

//COMプログラミングVC->VB6.0 Visual C++で、 main.cpp , NumberClass.h , NumberClass.cpp , NumberIDL.idl ファイルを以下のコードで作成し、 実行しましたら、正常にコンソールアプリケーションが動作しました。 次に、 VisualBasic6.0から参照設定で、Number.tlbというタイプライブラリを読み込ませて実行させたところ、「Functionまたは変数が必要です。」とエラーが表示されました。 どうすれば解決できますか?よろしくお願いします。 VB6.0のコード Private Sub Command1_Click() Dim a As NumberLibrary.NumberClass Dim b As Long b = a.Add(15, 35) End Sub //main.cpp #include<stdio.h> #include<string.h> #include"NumberClass.h" int main() { NumberClass Number; printf("%d",Number.Add(10,90)); getchar(); return 0; } //NumberClass.h class NumberClass { private: int num; public: int Add(int a,int b); void Save(int a); void Load(int *a); }; //NumberClass.cpp #include"NumberClass.h" int NumberClass::Add(int a,int b) { return a+b; } void NumberClass::Save(int a) { num=a; return; } void NumberClass::Load(int *a) { *a=num; return; } //NumberIDL.idl import "oaidl.idl"; import "ocidl.idl"; [uuid(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),version(1.0)] library NumberLibrary { importlib("stdole2.tlb"); [uuid(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx), object] interface INumber : IUnknown { HRESULT Add([in]int a,[in]int b); HRESULT Save([in]int a); HRESULT Load([out]int *a); }; [uuid(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)] coclass NumberClass { interface INumber; } };

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

  • ベストアンサー
  • nitscape
  • ベストアンサー率30% (275/909)
回答No.1

外部から呼び出せるCOMサーバーを作る場合はレジストリに登録する必要があります。またVBで使う場合にはCreateObject()を使ってオブジェクトを生成し Set a = CreateObject("xxxxxxxxxxxxxx") b = a.Add(15, 35) のようになります。 この2点の理由によって正常に動作していないのだと思います。 またmain()での使い方も普通のclassと同じ使い方になっています。外部から呼び出せるようなCOMオブジェクトを作るのでしたら普通はCoCreateInstance()を使ってオブジェクトを生成する方法になるかと思います。 厳しいことを言うようですが、もう一度「COMとは何か?」という基礎から始めた方がいいと思います。

HokUebun
質問者

お礼

回答ありがとうございます。 詳しく教えてくださって感謝しています。 タイプライブラリが生成されたときは、 COMが出来たんだとばかり思っていましたが、 全然でした。 はい、基礎から勉強します。 ありがとうございました。

その他の回答 (2)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

C++のアプリの方、こんなのCOMじゃないんですけど(^^;;; ただのC++のクラスを、タイプライブラリがあればVBから使えるとお思いですか? 勉強しなおしてください。 最低限、IDLに自分で書いているIUnknownが何なのかは理解しないとどうしようもないですね。 VB側も、#1の方の指摘のとおり、使い方間違ってますし。 #VC++でしたら、個人的にはCOMの作成はATLをお勧めします。

HokUebun
質問者

お礼

回答ありがとうございます。 そうですね。 自分もなんかおかしいなとは思っています。 ご指摘ありがとうございました。 勉強のほうはゆっくりやっていきます。 また、解らないことがあれば教えてください。 お願いします。 とりあえず、今は、 interfaceやIUnknown等の勉強をしています。

  • jmh
  • ベストアンサー率23% (71/304)
回答No.2

こんばんは。 HRESULT Add([in] int a, [in] int b) には、[out, retval] がないので、VB では Sub に見えると思います。

HokUebun
質問者

お礼

こんばんわ。 回答ありがとうございます。 [out, retval]がなければ値を返さないのですね。 良く解りませんでした。 ご指摘ありがとうございます。 とりあえず、今は初歩に帰っています。

関連するQ&A

  • 分割コンパイルについて

    現在分割コンパイルが分からずに苦戦しています。 下記のリストは構造体を使わなければコンパイラを通すことができましたが、 使うとなぜか通りません。 あれこれ試しましたがどうしても分かりません。 何がおかしいのでしょうか? *define.hで全てのファイルへの定義や宣言を行わせています。 ////////////// //Main.cpp ////////////// #include <stdio.h> #include <conio.h> #include "define.h" int main( void ){ Tmp[0].c = 15; printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); aaa(); bbb(); getch(); return 0; } ////////////////// // A.cpp ///////////////// #include <stdio.h> #include "define.h" void aaa( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // B.cpp ///////////////// #include <stdio.h> #include "define.h" void bbb( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // define.cpp ///////////////// #include "define.h" int a = 10; int b = 20; struct Parameter { int c; }; struct Parameter Tmp[NUM]; ////////////////// // define.h ///////////////// #define NUM 100 extern int a; extern int b; extern struct Parameter Tmp[NUM]; void aaa( void ); void bbb( void );

  • IDLファイルからソースファイルの実装方法について

    MessageDll.idlファイルで以下のようにコードを書いて、コンパイルしてできた MessageDll_h.hをインクルードして、 MessageComponent.cppに以下のように記述しました。 実装方法を教えてください。 また、間違っている所は指摘して頂きたいです。 DllRegisterServerとか足りない所はありますが、class内部だけでもお願いします。 お願いします。 //MessageDll.idl import "oaidl.idl"; import "ocidl.idl"; [uuid(7BBCC3A6-033D-4306-BC3D-EA358549F30F),version(1.0)] library ComputerLibrary { importlib("stdole2.tlb"); [uuid(9CAEC929-7E14-4af3-80EE-3D4EFECB3DCC), object] interface IMessage : IUnknown { HRESULT Message(); }; [uuid(0689B073-989C-483c-9757-0770F90A8C86)] coclass MessageClass { [default] interface IMessage; }; }; //MessageComponent.cpp #include"MessageDll_h.h" class MessageClass : public IMessage { public: HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { // 指定されたIID(Interface ID)に応じて、そのインターフェースポインタを // *ppvObjectに渡してやります。 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IMessage)) { *ppvObject = static_cast<IMessage *>(this); } else { *ppvObject = NULL; return E_NOINTERFACE; } return S_OK; } ULONG STDMETHODCALLTYPE AddRef() { // 今は何もしません。 return 0; } ULONG STDMETHODCALLTYPE Release() { // Release関数は、その名の通りコンポーネントの開放を行います。 delete this; return 0; } HRESULT STDMETHODCALLTYPE Message() { MessageBox(NULL,"Hello World","",MB_OK); return 0; } };

  • C言語の質問です。

    #include"stdio.h" int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = a+b; printf("add=%d\n", add); return 0; } と、------------------------------------------------------------------------------ #include"stdio.h" int tasizan(int x, int y); int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = tasizan(a, b); printf("add=%d\n", add); return 0; } int tasizan(int x, int y){ int aa; aa = x + y; return aa; } の違いを教えてください。

  • IDLファイルとヘッダーファイルの関係

    IDLファイルに //DllRegist.idl import "oaidl.idl"; import "ocidl.idl"; [uuid(1709AE99-7F13-40fa-AE87-BBF66E9A6516), object,dual,pointer_default(unique)] interface IMsg : IUnknown { [id(1), helpstring("メソッド Box")] HRESULT Message(); }; [uuid(7CD8AFF7-293C-4a05-A998-3598EBBF2BB3),version(1.0)] library MessageLibrary { importlib("stdole2.tlb"); importlib("stdole32.tlb"); [uuid(AEB6B6D3-7B45-448e-977E-0A516C28F91D)] coclass Msg { [default] interface IMsg; }; }; として、 ヘッダーファイルに //Interface.h #include"Guid.h" #include<windows.h> interface IMsg : public IUnknown { virtual void Message()=0; }; とすると、 interfaceがふたつ出来るようです。 クラスビュー画面にて確認しました。 どうすればひとつになりますか? よろしくお願いします。

  • プログラミングについて教えてほしいんですが・・・

    プログラミングについて教えてほしいんですが・・・ プログラミングで四則演算プログラムをやっているのですが余りの求め方がわかりません。足し算の求め方は /*lesson2.c*/ #include<stdio.h> int add(int,int); int main(){ int a,b,c; printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); c=add(a,b); printf("a+b=%d\n",c); } int add(int x, int y){ return x+y; } というやり方で求めることができたのですが、余りは上のプログラムのどこを変えたらいいのでしょうか? 誰かわかる人がいたら教えてください。お願いします。

  • ヘッダのインクルード時のエラー

    初歩的な質問で恐縮です。 以下のようなファイルの構成でc++のプログラムを組んでいます。 <header.h> class H { public: virtual void func() = 0; }; <fileA.cpp> #include "header.h" class A : public H { public: void func() {} }; <fileB.cpp> #include "header.h" class B : public H { public: void func() {} }; <main.cpp> #include "fileA.cpp" #include "fileB.cpp" int main() { A a; B b; a.func(); b.func(); return 0; } これをビルドしようとすると、「クラス"H"を再定義しようとしています」とエラーが出てコンパイルができません。理屈は分かるのですが、これの対処方法が分かりません。この場合、header.hはJAVAにおけるInterfaceのような役割としてそれを使うfileA.cpp、fileB.cppの両者にインクルードしておきたいのです。これはどのようにして対処すべきなのでしょうか?

  • C言語のreturnの使い方

    return a, b; のように2つの引数で値を返せることを最近になり 知りました。ところで以下のような使い方は可能でしょうか? test( , )という2つの引数が必要な関数にnum()で return 1,2としてひとつの関数呼び出しで引数2個分に すると言うようなことです。 #include <stdio.h> int test( int i, int j){   printf("%d %d",i,j); } int num(void){   return 1,2; } int main(void){   test( num() ); }

  • 分割コンパイルの初歩

    C言語ですが、.hに実装を書くのは避けたほうが良いといわれます。 私は main.c define.h aaa.h bbb.h みたいなスタイルでコードを書いていました。 まずdefine.hでグローバル変数や、マクロなどの宣言を まとめて行い、ほかの.hやmain.cでも使えるようにして いました。 しかし、以下のような状況のとき、どのように分割すれば 良いのかが分かりません・・・。 たとえば、以下のように、マクロNUM、変数a,bをすべてのファイルで共有して使えるように分割コンパイルするにはどのようにコードを書き直せば良いのでしょうか? //--------------main.c------------------ #include "define.h" #include "aaa.h" #include "bbb.h" int main( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM);   aaa();   bbb();   return 0; } //------------define.h------------------ #define NUM 100 int a = 10; int b = 20; void aaa( void ); void bbb( void ); //------------aaa.h------------------ void aaa( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM); } //------------bbb.h------------------ void bbb( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM); }

  • Cプログラミング 初歩

    #include <stdio.h> int main (void){ double num; printf("実数を入力して下さい:"); scanf("%lf",&num); printf("あなたは%fと入力しましたね\n",num); return(0); } のプログラミングがコンパイル出来ません↓ printf("あなたは%fと入力しましたね\n",num); をprintf("%f\n",num);のようにすると上手くいくのですが、 どうしたらコンパイルできるか分かる人はいますか?

  • コンストラクタの順序?

    以下のソースに関して質問です。 /* library.h */ #pragma comment(lib, "library.lib") class A { public: A(); }; /* library.cpp */ #include "library.h" #include <list> class B { private: std::list<int> m_listi; public: void Func() { m_listi.push_back(0); //フリーズ return; } } g_CB; A::A() { g_CB.Func(); return; } /* test.cpp */ #include "library.h" A CA; int main() { return 0; } library.cppからlibrary.libをつくり、それをtest.cppで使用したところ、 ソースに示したところでプログラムがフリーズしてしまいます。 恐らくクラスBのm_listiが初期化される前にそれを使おうとしたためだと思います。 どうすればそれを避けられるでしょうか。。。

専門家に質問してみよう