vb.net调用vc6.0写的COM

liuka 2008-07-16 11:49:41
如题
COM中要返回一个VARIANT类型数据
我在 VC6.0 VB中都可以正常使用
但在vb.net下就提示
未处理的“System.ArgumentException”类型的异常出现在 VB.net.exe 中。

其他信息: 指定的记录无法映射到托管值类。
在C#下也是这样的错误
请问如何解决
...全文
170 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuka 2008-07-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xuda_peter_123 的回复:]
问题是你传入的VB.NET数据类型和COM的数据类型不能映射,

你传入的是Object类型, 而Object类型根本没有 vt, parray这样的属性,
所以就出现了问题.

注意VB.NET和COM组件进行交流时仅仅限于简单数据类型,比如String, int等,
自定义数据类型一般是不可以的.

[/Quote]
我换成SAFEARRAY
就可以了
liuka 2008-07-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xuda_peter_123 的回复:]
问题是你传入的VB.NET数据类型和COM的数据类型不能映射,

你传入的是Object类型, 而Object类型根本没有 vt, parray这样的属性,
所以就出现了问题.

注意VB.NET和COM组件进行交流时仅仅限于简单数据类型,比如String, int等,
自定义数据类型一般是不可以的.

[/Quote]
当我传一个结构体的时候可以在.net中使用 啊
现在就是传一个结构体数组的时候在.net中提示异常

我的结构体为
[uuid(8C58263A-838E-4bd0-889F-05A98B2288BB)]
typedef struct Room_Infor //房间信息
{
BSTR ID; //ID
BSTR name; //name
BSTR location;//区
BSTR status; //状态
} Room_Infor;

psa=SafeArrayCreateVectorEx(VT_RECORD,0,long(i_count),(void*)pRecordInfo);

当我把类型更换为VT_BSTR / VT_VARIANT 等都 又提示什么非托管到托管错误
我在网上找的好象只能用VT_RECORD表明自定义类型

  • 打赏
  • 举报
回复
应该是对传递的VT_RECORD类型封装的有问题。

我觉得应该只使用原始类型。
LONGLONG llval; // VT_I8.
LONG lVal; // VT_I4.
BYTE bVal; // VT_UI1.
SHORT iVal; // VT_I2.
FLOAT fltVal; // VT_R4.
DOUBLE dblVal; // VT_R8.
VARIANT_BOOL boolVal; // VT_BOOL.
_VARIANT_BOOL bool;
SCODE scode; // VT_ERROR.
CY cyVal; // VT_CY.
DATE date; // VT_DATE.
BSTR bstrVal; // VT_BSTR.
IUnknown * punkVal; // VT_UNKNOWN.
IDispatch * pdispVal; // VT_DISPATCH.



xuda_peter_123 2008-07-16
  • 打赏
  • 举报
回复
问题是你传入的VB.NET数据类型和COM的数据类型不能映射,

你传入的是Object类型, 而Object类型根本没有 vt, parray这样的属性,
所以就出现了问题.

注意VB.NET和COM组件进行交流时仅仅限于简单数据类型,比如String, int等,
自定义数据类型一般是不可以的.
liuka 2008-07-16
  • 打赏
  • 举报
回复
如下
[id(3), helpstring("method GetRoomList")] HRESULT GetRoomList([out]VARIANT *pRoomList,[out,retval]long *iCount);

STDMETHODIMP CCOM_DB::GetRoomList(VARIANT *pRoomList, long *iCount)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())

// TODO: Add your implementation code here

_RecordsetPtr pRs =NULL;
pRs.CreateInstance(__uuidof(Recordset));
CString m_ID,m_name, m_location, m_status;

if(pConn == NULL)
{
AfxMessageBox("连接已经失效");
return S_FALSE;
}
else
{


try
{

pRs->CursorLocation = adUseClient;
pRs->PutRefActiveConnection(pConn);
pRs->Open((_bstr_t)"select * from DB_Room",vtMissing,adOpenStatic,adLockBatchOptimistic,-1);
pRs->PutRefActiveConnection(NULL);

}
catch(_com_error &e1)
{
CString str;
str.Format("打开记录集失败!!!-%s",e1.ErrorMessage());
AfxMessageBox(str);
for(long i =0 ; i < pConn->Errors->GetCount(); i++)
{
AfxMessageBox(pConn->Errors->GetItem(_variant_t(i))->Description);
}
return S_FALSE;

}

*iCount = pRs->GetRecordCount();
long i_count = 0;
i_count = pRs->GetRecordCount();

Room_Infor *RoomStruct = NULL;

VariantInit(pRoomList);

SAFEARRAY *psa = NULL; //安全数组的定义
// SAFEARRAYBOUND sad[1];
// sad[0].cElements = i_count;
// sad[0].lLbound = 0;
// psa = ::SafeArrayCreate(VT_VARIANT,1,sad);


IRecordInfo* pRecordInfo=NULL;
// {8C58263A-838E-4bd0-889F-05A98B2288BB}
static const GUID IID_STRUCT_ROOM =
{ 0x8c58263a, 0x838e, 0x4bd0, { 0x88, 0x9f, 0x5, 0xa9, 0x8b, 0x22, 0x88, 0xbb } };


HRESULT hr=::GetRecordInfoFromGuids(LIBID_DBCOMLib,1,0,GetUserDefaultLCID(),IID_STRUCT_ROOM,&pRecordInfo);

if(FAILED(hr))

return E_FAIL;

psa=SafeArrayCreateVectorEx(VT_RECORD,0,long(i_count),(void*)pRecordInfo);


pRoomList->vt = VT_ARRAY|VT_RECORD;
pRoomList->parray = psa;

SafeArrayAccessData(psa, (void**)&RoomStruct);//获取SafeArray的数据的指针

for(long m=0; m < i_count; m++)
{

m_ID = GetAsString(pRs,"Rid");
m_name = GetAsString(pRs, "name");
m_location = GetAsString(pRs,"location");
m_status = GetAsString(pRs, "status");
RoomStruct[m].ID = m_ID.AllocSysString();
RoomStruct[m].name = m_name.AllocSysString();
RoomStruct[m].location = m_location.AllocSysString();
RoomStruct[m].status = m_status.AllocSysString();

pRs->MoveNext();
}

SafeArrayUnaccessData(psa);//add!

pRs->AddRef();
return S_OK;
}
}
  • 打赏
  • 举报
回复
COM 是怎么写的?
liuka 2008-07-16
  • 打赏
  • 举报
回复
Dim var As Object
Dim abc() As DBCOMLib.Room_Infor
Dim Count As Long

Count = ob.GetRoomList(var) -->提示 指定的记录无法映射到托管值类。
abc = var
  • 打赏
  • 举报
回复
你怎么返回的?

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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