接口在VC中定义用Delphi调用 ( 积分: 300 )

  • 主题发起人 godelphi2004
  • 开始时间
G

godelphi2004

Unregistered / Unconfirmed
GUEST, unregistred user!
在VC中不使用IDL如何定义一个接口?这个接口如何用Delphi调用?
如果能有一个简单的Demo演示一下就最好了:)
提示:请各位看清题意再回答,灌水就不要了[:(]
说明:
一、本题不是问怎么写COM,而是问怎么用VC写接口;而且写的时候[red]不能使用IDL[/red];
二、Delphi调用可以手工翻译VC接口定义文件的,只是现在我翻译的可能有点问题;因为是手工翻译接口,所以用不着Type Library;
三、回答本题可能需要对VC和Delphi生成的接口内存布局以及对相应的调用机制有深入的了解;
 
在VC中不使用IDL如何定义一个接口?这个接口如何用Delphi调用?
如果能有一个简单的Demo演示一下就最好了:)
提示:请各位看清题意再回答,灌水就不要了[:(]
说明:
一、本题不是问怎么写COM,而是问怎么用VC写接口;而且写的时候[red]不能使用IDL[/red];
二、Delphi调用可以手工翻译VC接口定义文件的,只是现在我翻译的可能有点问题;因为是手工翻译接口,所以用不着Type Library;
三、回答本题可能需要对VC和Delphi生成的接口内存布局以及对相应的调用机制有深入的了解;
 
IDL只是定义接口,而未实现。VC里对接口的定义通过纯抽象类进行。Delphi调用VC的接口,其实是Delphi调用VC写的COM,只要COM里带Type Library,在Delphi里将其Import进来即可。Type Library有些类似编译后的IDL,以Binary形式的资源方式存在实现COM的DLL或EXE里。
 
在VC下做成DL(COM),注册后,在Delphi可Import后,即可调用。
 
Delphi里面要调用可以 Project/Import Type Library
 
首先感谢各位的回复[:)]
其次请各位富翁看清题意,如果是要使用COM/Type Library机制那这个帖子就没有存在的必要了[:(]
 
不用COM/Type Library调个鬼?! 跨语言调用总得有跨语言调用的机制,没有相应机制,楼主不是搞笑嘛。难不成楼主想自己搞个“机制”出来?这下搞大了!有好消息通知我,让咱也瞻仰瞻仰。
(楼主有什么新思路?说出来听听,这个问题还是蛮有兴趣滴)
 
楼上的,是不是搞笑我不想多说,建议你先去看看《 Essntial COM 》,搞搞清楚 COM 的由来再来说话吧[:(]
 
楼主知道答案就说出来,本来论坛是大家讨论的,何必搞得就为了显罢学问似的,似乎别人都是菜鸟。有不对的你指出,但好歹也得说出个子丑寅卯来,让咱也佩服一下,一句“搞搞清楚 COM 的由来再来说话吧”就打发了?还是没让人发现你学问高在哪?哥们,下点猛料让众鸟没话说,才能证明你是超人。
 
楼上的是想吵架么???[:(!][:(!][:(!]
你搞清楚我可是来问问题的,不是来听你教训的,你如果知道欢迎讨论,如果不知道也没有人逼你开口不是?
而且到底是谁在“显罢”???有人先是认为别人的想法是“搞笑”,接着嘲笑“难不成楼主想自己搞个“机制”出来?”照你这个想法,如果你认为办不到的事情就是不可能的罗,象我这样的菜鸟搞什么搞???大家可看清楚了这是谁在“显罢”???
看样子你是天下万物无所不知啊,你不知道的那肯定是不存在的了,这是谁在狂妄?谁在“显罢”???
 
Project->Import Type Library,ADD用VC写的COM的然后Create Unit然后Uses生成的单元,看看单元里的申明就知道怎么回事了的。
 
学习学习!!
还没有搞过这方面的问题!
 
自己顶,真想听到一个实在的答案
现在的大富翁啊,怎么说呢。。。
 
DELPHI如何生命一个接口自不用说。
VC中如果使用IDL声明接口,可以用MIDL转换成*.H,其实在编译的时候也使用了MIDL。因此只要你有合适的*.h文件,那么仍然可以。
而在头文件中声明接口,其实就是声明纯虚类,然后在实现的时候利用多重继承而已.
class IIntf
{virtual int get_IntValue() = 0;}
这就是一个接口的声明.
在实现的时候
class CIntf : IIntf
{
...
}
如果你的接口要实现IUnknown.那么class IIntf : IUnknown{...}.
如果你的接口不实现IUnknown,那么你可以不用实现QueryInterface/Addref等函数.
 
To: zjan521
非常感谢您的回复,用纯虚类的方法声明本人已经实现了,当然在对应的Delphi接口定义中也要声明成纯虚类才行,这样是没有一点问题的;
我现在想要实现的是这样的声明:
interface IIntf : IUnknown{...}.
IUnknown的三个方法也实现了,对应的Delphi接口定义中也声明为interface了,可是就是在这种情况下怎么也通不过(编译没有问题,但在调用时出错):(
我的猜想是,Delphi和VC在对接口变量的处理上面是不同的,在Delphi中给一个接口变量赋值时,会调用IntfCopy和IntfClear,而在VC中不会做任何处理的,这是其中的一个不同,也许正是由于这个不同和其他我不知道的不同才造成了我现在的问题;并且这个接口我使用Delphi定义用Delphi来调用也是没有任何问题的,真是郁闷啊。。。
 
关注,长见识,com的东西我也写过一些,和还是不明白楼主的意图
 
多谢楼上的关注,就是在VC中写接口了,然后从DLL输出一个函数以获取这个接口指针,之后就可以调用接口方法了,这个思路在Delphi中是很容易实现的,可能是因为我VC不熟悉所以弄迷糊了[:(]
 
应该是不难实现,我现在没有时间作试验,不过你可以试一试
////////////////////////////////////////vc
interface IMyIntface
{
viod method1();
int method2();
}
Class MyInterfaceImplment : public IMyIntface
{
__stdcall method1();
__stdcall int method2();
}
///////////////////////////////////////////
// dll export Function
///////////////////////////////////////////
CreateMyObject(LPVOID* pout)
{
*pout = new MyInterfaceImplment;
}
////////////////////////////////////////////////////
// delphi
///////////////////////////////////////////////////
interface IMyIntface
procedure method1();
stdcall;
function method2();
integer;
stdcall;
end;

procedure MyFun1();
var
pMyIntface: IMyIntface;
beign
loadlibrary
CreateMyObject := getProcAddress
CreateMyObject(@pMyIntface);
if ( nil = pMyIntface ) then
exit;
pMyIntface.method2();

end;
你试一下,我只是写了一个思路,我没有具体实现,还有一些错误判断也都没有
 
非常感谢RailGundi,你的这个代码思路是完全正确的,我现在的代码也基本是这样的,出问题在我将interface IMyIntface改为interface IMyIntface : public IUnknown之后,之后在Delphi中调用就出问题了,我已经实现了IUnknown的三个方法[:(]
 
1.首先判定你所谓的错误是什么错误,也就是说,调用错误(没有得到正确的接口,或得到的接口的VMT错误) 还是 实现错误(1.接口计数,实现不合规矩,导致对象不能释放/提前释放2.借口查询实现错误).
2.调用错误很同意排除.在你的接口(包括IUnknown)的每个函数所有代码之前,添加一个LOG语句.(或者直接嵌入汇编 __asm{int 3;},然后会产生断点,这样可以根据汇编代码判定是否是正确的函数.(可以添加一些指令比如nop或者跳转+标号))
如果是这个错误,多半是你的 QueryInterface/引用计数 实现错误导致,
3.如果上面的错误排除了,那么改成在VC中调试DLL.这样可以调试DLL地实现.这个就没有什么可讲的了.
4.其实你最好现在VC下边调试完成.
如果你明天还不能完成,那么我明天写一个简单的DEMO给你.
 
顶部