一个VC6写的Filter自定义接口,在delphi7下访问有问题

crazycock 2008-11-21 02:45:29
一个用vc6写的source filter,在delphi7下面访问没有问题。为了控制这个source filter的一些设备有关的特性,自定义了一个接口,只有一个测试函数int Add(int n1,int n2),return n1+n2,就这么简单,但是接口query到了以后,在vc里调试发现,delphi那边Add(1,2)的话,vc函数里单步看到n1是一个莫名其妙的值,n2则为1。后来经过测试,发现如果测试函数定义的参数里面多加一个,例如int Add(int n0,int n1,int n2),那么delphi那边Add(1,2,3),vc里就会看到n0为莫名其妙的值,n1=1,n2=2,仿佛错位了4个字节(int类型)一样。不知道什么缘故?

下面是部分代码:
//----------------Delphi里--------------------------------
const
IID_ISimpleMath : TGUID = '{A555C1E8-69A2-4D4D-A60C-AA65E668951C}';

type
{$HPPEMIT 'typedef System::DelphiInterface<ISimpleMath> _di_ISimpleMath;'}
{$EXTERNALSYM ISimpleMath}
ISimpleMath = interface(IUnknown)
['{A555C1E8-69A2-4D4D-A60C-AA65E668951C}']
function Add(nOp1:Integer;nOp2:Integer):Integer;stdcall;
end;






//-------------VC里----------------------------------------
STDMETHODIMP CMath::QueryInterface(REFIID riid, void **ppv)
{
// 这里这是实现dynamic_cast的功能,但由于dynamic_cast与编译器相关。
if(riid == IID_ISimpleMath)
*ppv = static_cast<ISimpleMath*>(this);
else if(riid == IID_IUnknown)
*ppv = (this);
else {
*ppv = 0;
return E_NOINTERFACE;
}
AddRef(); //这里要这样是因为引用计数是针对组件的
return S_OK;
}
STDMETHODIMP_(ULONG) CMath::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CMath::Release()
{
ULONG res = --m_cRef; // 使用临时变量把修改后的引用计数值缓存起来
if(res == 0) // 因为在对象已经销毁后再引用这个对象的数据将是非法的
delete this;
return res;
}

int CMath::Add(int nOp1, int nOp2)
{
return nOp1+nOp2;
}


CMath::CMath()
{
m_cRef=0;
}

//-------接口定义部分--------------
#include "interface.h"

class CMath : public ISimpleMath
{
private:
ULONG m_cRef;
public:
CMath();
//IUnknown Method
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
//  ISimpleMath Method
int Add(int nOp1, int nOp2);
};
...全文
130 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
crazycock 2008-11-22
  • 打赏
  • 举报
回复
效率真高,wwwllg果然是个热心人。最后还是用idl解决的,我没有看明白idl的代码,不过照葫芦画瓢总会的,回头有空再细看代码吧。

贴上来idl的代码。

import "unknwn.idl";
import "wtypes.idl";



[
uuid(ECDB7B12-65C2-487D-A973-D0A4FA7ACDF4),
version(1.0),
helpstring("DeviceCfg 1.0 Type Library")
]
library DeviceCfgLib
{
[
object,
uuid(F6A648D1-C4C6-42E5-903A-666084eF0EAE)
]

interface IDeviceCfg : IUnknown
{
[helpstring("method Add")] HRESULT Add([in]long n1,[in]long n2,[out,retval]long* pRet);
[helpstring("method Sub")] HRESULT Sub([in]long n1,[in]long n2,[out,retval]long* pRet);
};

[
uuid(79C497DA-3B4A-4D69-BB9C-B4FA9845924B),
helpstring("")
]
coclass CDeviceCfg
{
[default] interface IDeviceCfg;
};
};
UDX协议 2008-11-22
  • 打赏
  • 举报
回复
你加我msn,我帮你实现一个方法吧。我正好有空现在。
ruby.li#wswtek.com

#->@
crazycock 2008-11-22
  • 打赏
  • 举报
回复
帖子加100分,希望大家多多关注。
crazycock 2008-11-22
  • 打赏
  • 举报
回复
你好wwwllg,我的自定义接口是这样写的。

#ifndef INTERFACE_H
#define INTERFACE_H
#include <unknwn.h>

//
static const GUID IID_ISimpleMath = {0xA555C1E8,0x69A2,0x4D4D,0xA6,0x0C,0xAA,0x65,0xE6,0x68,0x95,0x1C};


interface ISimpleMath : public IUnknown
{
public:
virtual int Add(int nOp1, int nOp2) = 0;
};


#endif  


是不是要从IDispatch继承得到自定义接口?确实,其它Filter的接口,在delphi下访问都是正确的,应该是我自己添加的接口哪里没有写对,所以delphi没能正确访问。不知道wwwllg是否可以提供一个Sample供参考一下,因为对COM不是很熟。
UDX协议 2008-11-22
  • 打赏
  • 举报
回复
这是你的接口实现问题。感觉你这个好象一般的函授调用,因为delphi和vc参数是反向的。
在com里面他不会出现这种问题。
我不知道你的操作哪里出了问题。我没有看到你filter头文件及实现。
但我把正确的步骤说一下。

1.idl中接口从dispatch派生。
2,给接口增加add方法。
3,你的filter实现该方法。
4.注册filter

实际上操作和一般的activex编写差不多,这样delphi就可以正确的识别了。

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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