1 / 15

VC 编写组件中的问题

VC 编写组件中的问题. 1. 在定义函数参数时是否需要使用 retval 。 retval 的作用是把此参数作为函数的返回值。例如: [out,retval] BSTR *p 那就是说,* p 被作为函数的返回值。 可以用在接口成员函数的参数上,或者用在属性接口成员参数上 注意:::: (1) 此属性只能使用在函数的最后一个参数上。 (2) 此参数只能使用在为返回类型的参数 [out] 上,不能使用在 [in] 或者 [inout] 参数上。 (3) 而且此参数必须是指针类型。. VC 编写组件中的问题. 1. 使用此属性

kineks
Download Presentation

VC 编写组件中的问题

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. VC编写组件中的问题 • 1. 在定义函数参数时是否需要使用retval。 retval的作用是把此参数作为函数的返回值。例如: [out,retval] BSTR *p 那就是说,*p被作为函数的返回值。 可以用在接口成员函数的参数上,或者用在属性接口成员参数上 注意:::: (1) 此属性只能使用在函数的最后一个参数上。 (2) 此参数只能使用在为返回类型的参数[out]上,不能使用在[in]或者[inout]参数上。 (3) 而且此参数必须是指针类型。

  2. VC编写组件中的问题 • 1. 使用此属性 如果使用了此属性,那么最后一个参数就被作为函数的返回值,那么在VB中进行调用如下: dim object1 as new hellolib.Greet dim disp as string disp=object1.get_Greeting Text1.text=disp

  3. VC编写组件中的问题 • 2. 不使用此属性 如果不使用此属性,那么就只能从函数调用时的参数中获得此函数的值, 因此在VB中进行调用就要修改,其调用如下: dim object1 as new hellolib.Greet dim disp as string object1.get_Greeting disp Text1.text=disp 此时的disp就被作为函数定义时的参数*p的值,此参数中存什么值,disp就是什么。 作为返回值时可用等号,不作返回值时,只能取获得对应参数的值。

  4. VC编写组件中的问题 • 3.下面的代码将更清楚: 组件的中接口成员函数的定义如下: [helpstring("method get_Greeting")] HRESULT get_Greeting([out] BSTR *p1,[out] BSTR *p2); 实现如下: CComBSTR bstr1("Hello"),bstr2("World"); *p1=bstr1.Detach(); *p2=bstr2.Detach(); return S_OK; 那么*p1和*p2都不作为函数的返回值。

  5. VC编写组件中的问题 • 3. 那么在VB中对其调用就相应如下: Dim object1 As New HelloLib.Greet Dim disp1 As String Dim disp2 As String object1.get_Greeting disp1, disp2 Text2.Text = disp1 Text1.Text = disp2 对应的disp变量就为函数定义中的参数*p1,disp2变量就为函数定义中的参数*p2。

  6. 用VC来做客户程序 • 1 . 新建一个MFC Appwizard[exe]工程 • 2. 给一个工程名helloclientc,确定 • 3. 选择基本对话框 • 4. 然后点击完成----确定 • 5. 进入程序编辑状态 • 6. 把生成的组件文件中的hello.tlb从服务器目录拷贝到客户目录中。 • 7. 把下列的include和import语句加入到头文件stdafx.h中。

  7. 用VC来做客户程序 • 加入后如下: #include <afxwin.h> #include <afxext.h> #include <afxdisp.h> #import “hello.tlb" no_namespace 其中的import被用来从一个类型库中取出信息,这个被引入的类型库就被转变为正在编写程序的C++类,这一命令最多用来描述COM接口。 • 8. 编译该工程并确认没有错误。 • 9. 通过执行下列CHelloclientcDlg::OnOK()的操作,对COM服务器做一个简单的测试。 创建一个指向COM对象的指针 调用方法get_Greeting 在EDIT中显示字符串

  8. 用VC来做客户程序 • 代码如下: // TODO: Add extra validation here IGreetPtr pGreet("hello.Greet.1"); BSTR bstr; bstr=pGreet->get_Greeting(); _bstr_t greeting; greeting=bstr; SetDlgItemText(IDC_EDIT1,greeting);

  9. 用VC来做客户程序 • 10.编译并运行客户程序。该程序启动后立即关闭,没有显示任何输出结果。 • 11. 可以对其进行出错处理,处理如下: try{ IGreetPtr pGreet("hello.Greet.1"); BSTR bstr; bstr=pGreet->get_Greeting(); _bstr_t greeting; greeting=bstr; SetDlgItemText(IDC_EDIT1,greeting);} catch(_com_error&ex){ MessageBox(ex.ErrorMessage());}

  10. 用VC来做客户程序 • 12. 再编译运行,将得到一个没有初始化OLE的错误信息 • 13. 由于客户程序是MFC类库应用,可以通过调用InitInstance的AfxOleInit来初始化OLE.代码如下: BOOL ChelloclinetcApp::InitInstance() { // Initialize OLE libraries if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } } • 14. 再次编译并运行该程序,该程序就可以正常工作了。这样便可以得到要显示的值。

  11. 用VC来做客户程序 • 注意是两个[out]参数,就应如此来处理: try { IGreetPtr pGreet(“hello.greet.1"); BSTR greeting1,greeting2; pGreet->get_Greeting(&greeting1,&greeting2); _bstr_t greet1(greeting1); _bstr_t greet2(greeting2); SetDlgItemText(IDC_EDIT1,greet1); SetDlgItemText(IDC_EDIT2,greet2); } catch(_com_error&ex) { MessageBox(ex.ErrorMessage()); } 参数对应,在此传递的是地址,而非值。

More Related