关于VB写的COM在VC中调用的问题(如何调用啊)

whn 2003-08-22 10:23:57

关于VB写的COM在VC中调用的问题(如何调用啊)

我同事用VB做了一个COM,我在VC中如何调用啊,好像VB做时就产生一个com dll文件
但VC使用COM都要头文件啊,是不是要别的什么东西啊,急用!
...全文
66 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lookmai 2003-09-17
  • 打赏
  • 举报
回复
VC肯定能调用VB的com,用VB写的com已经包含有自动化接口,方便各种脚本语言的调用.
VC调用VB写的com用多种办法.我只介绍其中两种.首先Create the Visual Basic Server.

Create a "testcom1" ActiveX DLL project. create a "testget" class
Add the following code to "testget":

Public Function loadPO(ByVal one As String, ByVal two As String) As String
loadPO = one & " and " & two
End Function

Compile the DLL as d:\testcom1.dll and exit Visual Basic.


一、前绑定,相当VB的Dim obj As New testcom1.testget
1.Visual C++6.0:File-->new-->Projects-->Win32 Application(project name)-->testcom3,就选第一项"An empty project"......
2.File-->new-->C++ Source File-->testcom3.输入以下内容到testcom3.cpp
//
#include "windows.h"
#include "testcom3.h"
#include <comutil.h>
#pragma comment(lib, "comsupp.lib")

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
CoInitialize(NULL);
_testget *pClass = NULL;
HRESULT hr=CoCreateInstance(CLSID_testget, NULL, CLSCTX_INPROC_SERVER, IID__testget, (void**)&pClass);
BSTR One=SysAllocString(L"first");
BSTR Two=SysAllocString(L"second");
BSTR Three;
hr = pClass->loadPO(One,Two,&Three);
char *p = _com_util::ConvertBSTRToString(Three);
MessageBox(NULL,p,"Access Check",MB_OK | MB_ICONINFORMATION);
SysFreeString(One);
SysFreeString(Two);
SysFreeString(Three);
pClass->Release();
CoUninitialize();
return 0;
}
//
3.Click OLE/COM Object Viewer on the Tools menu. Select View Typelib from the File menu and choose the testcom1.dll you created earlier. Click Open to display the ITypeLib Viewer, which contains the .idl file for your DLL.
4.Copy the contents of your .idl file (contents of the right pane) to the Clipboard. Hold the SHIFT key down while paging or scrolling from the first character to the end of the text in the pane. Press Ctrl+C to copy the marked text to the Clipboard.
5.Click New on Visual C++ File menu. Select Text File on the New dialog box, name the file testcom3.idl, and click OK.
6.A blank text file appears. Paste the data from the Clipboard into it and save the file.
7.Select Settings from the Project menu, expand the testcom3 and Source Files nodes of the tree view, and select testcom3.idl. Click the MIDL tab, enter testcom3.h in the "Output header file name" box, and click OK.
8.打开testcom3.idl,执行Build-->Compile testcom3.idl,在当前目录下生在testcom3.h和testcom3_i.c两个文件.
9.将testcom3_i.c加到Source Files,testcom3.h加入Header Files.
10.run.

二、后绑定,相当VB的set obj=server.createObject("testcom1.testget").采用VB的自动化接口.
1.Visual C++6.0:File-->new-->Projects-->Win32 Application(project name)-->testcom1,就选第一项"An empty project"......
2.File-->new-->C++ Source File-->testcom1.输入以下内容到testcom1.cpp
//
#include "windows.h"
#include <comutil.h>
#pragma comment(lib, "comsupp.lib")

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
CoInitialize(NULL);
CLSID clsid;
CLSIDFromProgID(L"testcom1.testget", &clsid);
IDispatch* pIDispatch=NULL;
CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pIDispatch);
DISPID dispid;
OLECHAR FAR* szMemberName = L"loadPO";
pIDispatch->GetIDsOfNames(IID_NULL,
&szMemberName,
1,
LOCALE_SYSTEM_DEFAULT,
&dispid);
DISPPARAMS dispparams;
dispparams.cArgs=2; //two arguments
dispparams.cNamedArgs=0; //no named arguments
dispparams.rgdispidNamedArgs=NULL;
dispparams.rgvarg=new VARIANTARG[2]; //the arg array contains two variants
//REMEMBER: arguments in the rgvarg array are reversed in order,
//so the last method argument is rgvarg[0] !
dispparams.rgvarg[0].vt=VT_BSTR; //a BSTR
dispparams.rgvarg[0].bstrVal=SysAllocString(L"second"); //allocate the BSTR
dispparams.rgvarg[1].vt=VT_BSTR; //a BSTR
dispparams.rgvarg[1].bstrVal=SysAllocString(L"first"); //allocate the BSTR
VARIANTARG Result;
Result.vt= VT_BSTR;
//Result.
EXCEPINFO excep;
//argument error information
UINT uArgErr;
pIDispatch->Invoke(dispid,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dispparams,
&Result,
&excep,
&uArgErr);
//if(Result.bstrVal=="hello")
char *p = _com_util::ConvertBSTRToString(Result.bstrVal);
MessageBox(NULL,p,"Access Check",MB_OK | MB_ICONINFORMATION);
SysFreeString(dispparams.rgvarg[0].bstrVal);
//delete the argument array
delete[] dispparams.rgvarg;
CoUninitialize();
return 0;
}
//
1方法效率高,是主流的使用方法,方法2的Invoke接口比较耗时.
wenn 2003-09-16
  • 打赏
  • 举报
回复
VC用VB的com,真的会发生了很多事,很多是没法解决的,也是没法预料的。还是纯一点吧,别太杂
flinming 2003-09-16
  • 打赏
  • 举报
回复
up
wangweixing2000 2003-09-16
  • 打赏
  • 举报
回复
我刚找到个好办法

用SafeArray传。下面是代码:
void CMyIeDlg::putArrays()
{
HRESULT hr;
SAFEARRAY* psaStudent = NULL;
SAFEARRAYBOUND rgbounds = { 4, 0 };
studentsInfo *pStudentStruct = NULL;

psaStudent = SafeArrayCreate(VT_VARIANT, 1, &rgbounds);
hr = SafeArrayAccessData(psaStudent, reinterpret_cast<PVOID*>(&pStudentStruct));

pStudentStruct[0].grade = 3;
pStudentStruct[0].name = SysAllocString(L"Shaun");
pStudentStruct[0].type = class_Clown;
pStudentStruct[1].grade = 8;
pStudentStruct[1].name = SysAllocString(L"Fred");
pStudentStruct[1].type = school_Bully;
pStudentStruct[2].grade = 12;
pStudentStruct[2].name = SysAllocString(L"Steve");
pStudentStruct[2].type = teachers_Favorite;
pStudentStruct[3].grade = 3;
pStudentStruct[3].name = SysAllocString(L"Linda");
pStudentStruct[3].type = teachers_Favorite;

hr = SafeArrayUnaccessData(psaStudent);
m_array.vt = VT_ARRAY;
m_array.parray = psaStudent;

}

void CMyIeDlg::getArrays()
{
HRESULT hr;
SAFEARRAY* psaStudent = NULL;
studentsInfo *pStudentStruct = NULL;
studentsInfo students[4];

psaStudent = m_array.parray;
hr = SafeArrayAccessData(psaStudent, reinterpret_cast<PVOID*>(&pStudentStruct));
for(int i = 0; i<4;i++)
{
students[i].grade = pStudentStruct[i].grade ;
students[i].name = pStudentStruct[i].name ;
students[i].type = pStudentStruct[i].type ;
}
hr = SafeArrayUnaccessData(psaStudent);
}
双杯献酒 2003-09-15
  • 打赏
  • 举报
回复
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q194/8/73.ASP&NoWebContent=1
masterz 2003-09-11
  • 打赏
  • 举报
回复
check its vt value,
VariantInit(&sPort);
HRESULT hr=iAds->Get(_bstr_t("Serverbindings"),&sPort);
if(SUCCEEDED(hr))
{
if(sPort.vt ==VT_ARRAY|VT_VARIANT)
{
SAFEARRAY* psa = sPort.parray;
VARIANT* varArray=NULL;
SafeArrayAccessData(psa,(VOID**)&varArray);
UINT uDim = SafeArrayGetDim(psa);
if(1==uDim)
{
long lLbound,lRbound;
SafeArrayGetLBound(psa,1,&lLbound);
SafeArrayGetUBound(psa,1,&lRbound);
for(long i=lLbound;i<=lRbound;i++)
{
if(varArray[i].vt==VT_BSTR)
{
_bstr_t bstmp(varArray[i].bstrVal,true);
AfxMessageBox((LPCTSTR)bstmp);
}
}
SafeArrayUnaccessData(psa);
}
}
}
aiirii 2003-09-10
  • 打赏
  • 举报
回复
如可以,告訴我如何解決,我也被這個問題困了很久!
whn 2003-08-22
  • 打赏
  • 举报
回复
谢谢,我也找到答案了,
我再问一下,我从COM一个接口方法中得到一个VARIANT,里面数据是一个数组
数组是里面有PersonID,Name,Info
我怎么从VARIANT取得数组的内容啊
csdn_lee 2003-08-22
  • 打赏
  • 举报
回复
/////////////////////////////////////////////////////////////////////////////
// CSDITestApp:
// See SDITest.cpp for the implementation of this class
//
#include "MainFrm.h"
#import "d:\\MyDevelope\\UnitWork\\SkinExpert\\Test.dll" no_namespace

class CSDITestApp : public CWinApp
{
public:
CSDITestApp();
ITestPtr m_pTest;//ITest为接口名字
.....
}


/////////////////////////////////////////////////////////////////////////////
// CSDITestApp initialization

BOOL CSDITestApp::InitInstance()
{
AfxEnableControlContainer();

//初始化COM
if(FAILED(::CoInitialize(NULL)))
{
TRACE("Unable to initial COM\n");
}
m_pTest.CreateInstance(__uuidof(Skin));
//调用测试函数
m_pTest->TestComFun();
.....
}

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧