我的IDL文件如下(部分):[
uuid(54035A23-B92A-4239-B401-6022867DF53B),
helpstring("_ICashCodeEvents Interface")
]
dispinterface _ICashCodeEvents
{
properties:
methods:
[id(1), helpstring("method CashPolled")] HRESULT CashPolled([in]long lMoney);
[id(2), helpstring("method ReturnStatus")] HRESULT ReturnStatus([in]short sCode,[out,retval]boolean *pboolCancel);
}; [
uuid(F2C949F7-8203-435D-834D-9A0A3F60715F),
helpstring("CashCode Class")
]
coclass CashCode
{
[default] interface ICashCode;
[default, source] dispinterface _ICashCodeEvents;
};
使用"连接点实现向导"通过CProxy_ICashCodeEvents类实现的连接点,CProxy_ICashCodeEvents类中函数声明为:
HRESULT Fire_CashPolled(LONG lMoney);
HRESULT Fire_ReturnStatus(SHORT sCode, CHAR * pboolCancel);第一个问题是boolean是自动化兼容的类型呀?为什么在代理类中会将IDL里的boolean*改成CHAR*?
第二个问题是我用VB测试的时候,使用WithEvents声明了一个对象,但无法链接ReturnStatus事件,而CashPolled可以正常链接.
代码如下:
Private WithEvents cc As IHWDLib.CashCode
Private Sub cc_CashPolled(ByVal lMoney As Long)
MsgBox lMoney
End Sub
使用VB的IDE添加Sub cc_ReturnStatus的时候,VB弹出对话框,内容是:
"函数或接口标记为限制的,或函数使用了 Visual Basic 中不支持的自动类型"PS:
Visual C++ 6.0 sp6
Visual Basic 6.0 sp6
uuid(54035A23-B92A-4239-B401-6022867DF53B),
helpstring("_ICashCodeEvents Interface")
]
dispinterface _ICashCodeEvents
{
properties:
methods:
[id(1), helpstring("method CashPolled")] HRESULT CashPolled([in]long lMoney);
[id(2), helpstring("method ReturnStatus")] HRESULT ReturnStatus([in]short sCode,[out,retval]boolean *pboolCancel);
}; [
uuid(F2C949F7-8203-435D-834D-9A0A3F60715F),
helpstring("CashCode Class")
]
coclass CashCode
{
[default] interface ICashCode;
[default, source] dispinterface _ICashCodeEvents;
};
使用"连接点实现向导"通过CProxy_ICashCodeEvents类实现的连接点,CProxy_ICashCodeEvents类中函数声明为:
HRESULT Fire_CashPolled(LONG lMoney);
HRESULT Fire_ReturnStatus(SHORT sCode, CHAR * pboolCancel);第一个问题是boolean是自动化兼容的类型呀?为什么在代理类中会将IDL里的boolean*改成CHAR*?
第二个问题是我用VB测试的时候,使用WithEvents声明了一个对象,但无法链接ReturnStatus事件,而CashPolled可以正常链接.
代码如下:
Private WithEvents cc As IHWDLib.CashCode
Private Sub cc_CashPolled(ByVal lMoney As Long)
MsgBox lMoney
End Sub
使用VB的IDE添加Sub cc_ReturnStatus的时候,VB弹出对话框,内容是:
"函数或接口标记为限制的,或函数使用了 Visual Basic 中不支持的自动类型"PS:
Visual C++ 6.0 sp6
Visual Basic 6.0 sp6
解决方案 »
- 为什么我已经包含了某个头文件(其中包含某个函数定义),编译也通过了。但在cpp中右击该函数,选择“转到****的定义”时,确显示函数未定义。
- 如何实现vc中鼠标调整opengl画的图形
- 散分,顺便推荐下正在听的一张专辑
- 1句VB代码转VC
- 驱动程序和应用程序怎么实现交互?
- 想在Doc类中发送一个消息,使得View类中一个函数执行,怎么做?
- 高手,我怎么做到在开始时,有一个RadioButton被选中,属于那种默认的,不是通过鼠标去点中?
- 100分求《VISUAL C++.NET课程设计案例精编》光盘源代码
- 如何把宽字符当作函数参数传递出去?
- 项目文件的问题
- 排序中关于setitemdata的问题
- 怎么我的CTabCtrl控件添加不上Dialog?
[
object,
uuid(C8C090A7-361B-4484-BBD7-81479B34F01A),
dual,
helpstring("ISerialPort Interface"),
pointer_default(unique)
]
interface ISerialPort : IDispatch
{
[id(1), helpstring("method OpenPort")] HRESULT OpenPort([in]BYTE port,[in]long baud,[out,retval]boolean *pboolResult);
VB测试的时候,使用后绑定,即使用CreateObject来创建对象的话,OpenPort函数可以正常调用OpenPort函数,如下:
Dim sp
Set sp = CreateObject("IHWD.SerialPort")
sp.OpenPort 2, 9600
If (sp.IsOpened()) Then
sp.ClosePort
Else
MsgBox "未能成功打开串口"
End If但是使用前绑定,即现在VB中添加类型库的引用,然后直接用
Private mSP As New IHWDLib.SerialPort
来定义一个对象,如下代码报错:
mSP.OpenPort 2, 9600报的错误跟上一个一样:
"函数或接口标记为限制的,或函数使用了 Visual Basic 中不支持的自动类型" 看来是不支持boolean*?那么应该使用什么类型呢?boolean是自动化兼容的类型呀!
难道要使用BOOL吗?BOOL是通过typedef int BOOL定义的,应该不对吧?
boolean Unsigend char 不支持
byte Unsigend char 不支持
small char 不支持
short short Integer
long long Long
byper _int64 不支持
float float Single
double double Double
char unsigned char 不支持
wchar_t wchar_t Integer
enum enum Enum
VARIANT VARIANT Variant
BSTR BSTR String
VARIANT_BOOL sHORT{-1/0} Boolean{True/Flase}
VB中的后绑定不进行类型检查,而是尝试执行内部的VARIANT类型转换,从1字节的boolean转换成2字节的VARIANT_BOOL是能够成功的,所以运行结果看起来是成功的,但是前绑定会做类型检查,所以在编译期间就会提示类型错误。
如下函数: HRESULT Fire_ReturnStatus(SHORT sCode, VARIANT_BOOL * pboolCancel)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[2];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[1] = sCode;
pvars[0] = pboolCancel;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete[] pvars;
return varResult.scode;
}
编译的时候有一个警告:
warning C4800: 'short *' : forcing value to bool 'true' or 'false' (performance warning)
在pvars[0] = pboolCancel;这一行.
如何处理?
pvars[0].vt = VT_BOOL|VT_BYREF;
pvars[0].pboolVal = pboolCancel;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
编译过去了但是我从VB添加了如下代码
Private Function mCC_ReturnStatus(ByVal sCode As Integer) As Boolean
MsgBox sCode
mCC_ReturnStatus = True
End Function
这个函数不会执行到,确定上面的Invoke是执行了的,我单步跟进去看了的.VB中我还链接了另外一个事件,如下:
Private Sub mCC_CashPolled(ByVal lMoney As Long)
MsgBox lMoney
End Sub
这个是可以执行到的.
[id(2), helpstring("method ReturnStatus")] HRESULT ReturnStatus([in]short sCode,[out,retval]boolean *pboolCancel);把后面的retval属性去掉就可以了,但是不明白为什么不能用retval
我在IDL里面写的是VARIANT_BOOL*
但是生成的代理类里面是:
pvars[0] = pboolCancel;另外还有一个问题请教:
CCashCode类实现ICashCode接口,该类还包容了另一个接口ISerialPort,内部变量为ISerialPort *m_pSerialPort;
在ICashCode的某一个导出函数中,需要另外开一个线程.
该线程中需要使用包容的ISerialPort接口.我不知道怎么可以在该线程中使用IserialPort接口.
另外,如果线程函数中需要调用CCashCode的成员函数,是否直接传递this就行?不需要列集吧?
2.线程函数中需要使用包容的ISerialPort接口,还需要调用CCashCode类的某些函数(非ICashCode接口函数).这样的话,是需要列集ISerialPort和ICashCode两个接口吗?ICashCode接口需要列集吗?ISerialPort接口需要列集吗?
2.线程函数中需要使用包容的ISerialPort接口,还需要调用CCashCode类的某些函数(非ICashCode接口函数).这样的话,是需要列集ISerialPort和ICashCode两个接口吗?ICashCode接口需要列集吗?ISerialPort接口需要列集吗?
问题2:牢记一个原则,如果你使用的接口指针是一个代理接口,就不能使用非接口方法的函数;如果是在组件所在套间线程,可以把接口static_cast成对象指针再调用任何函数(包括非接口方法)
为什么COM的DLL就不行呢?class CCashCode:public ICashCode
...
{
public:
//ICashCode
ICashCode_Func1();protected:
static ULONG threadProc(LPVOID);
void Func2();private:
ISerialPort *m_pSerialPort; //包容之,在FinalConstruct中CoCreateInstance的.
};在CCashCode类的threadProc中,需要调用到Func2,而Func2中需要用到m_pSerialPort,应该怎么处理呢?
为什么做成COM的DLL就不行呢?
class CCashCode:public ICashCode
...
{
public:
//ICashCode
ICashCode_Func1(); protected:
static ULONG threadProc(LPVOID);
void Func2(); private:
ISerialPort *m_pSerialPort; //包容的ISerialPort接口,在FinalConstruct中进行的CoCreateInstance.
};
在CCashCode类的threadProc中,需要调用到Func2(非ICashCode接口的成员函数,是普通的类辅助函数),而Func2中需要用到m_pSerialPort,应该怎么处理呢?