怎么调用第三方DLL导出的Interface?
我想在C++中使用Delphi开发的DLL导出的接口实现
Delphi DLL
library Project1;
uses
Winapi.Windows, System.SysUtils;
type
ITest = interface(IUnknown)
function ShowInt(V1, V2: Integer): Integer stdcall;
end;
TTest = class(TInterfacedObject, ITest)
function ShowInt(V1, V2: Integer): Integer stdcall;
end;
function TTest.ShowInt(V1, V2: Integer): Integer;
begin
Result := 888;
end;
function Get: ITest stdcall;
begin
Result := TTest.Create;
end;
exports
Get;
begin
end.
很简单,定义了一个接口ITest,该接口有一个方法ShowInt,返回一个整数888
我在C++中这么写的
//ITest.h
#ifndef ITEST_H
#define ITEST_H
#include <Unknwn.h>
interface ITest : public IUnknown
{
virtual int __stdcall ShowInt(int v1, int v2) = 0;
};
#endif // ITEST_H
然后我尝试动态加载DLL并调用。用的Qt
QLibrary lib("Project1");
if (lib.load()) {
typedef ITest* (__stdcall *Get)();
Get method = (Get)lib.resolve("Get");
ITest *obj = method(); // 这里会发生异常
if (obj != nullptr) {
obj->ShowInt(777, 888);
}
}
搞了一天了……谁指点一下
[解决办法]
dll 并不跨语言,com 才是跨语言的。
dll 要通用,最好只使用 c 语言接口
[解决办法]
最好把接口指针放到智能指针里:
#include <boost/smart_ptr>
#include <cassert>
void intrusive_ptr_add_ref(ITest* p)
{
assert(p);
p->AddRef();
}
void intrusive_ptr_release(ITest* p)
{
assert(p);
p->Release();
}
typedef boost::intrusive_ptr<ITest> ITestPtr;
ITestPtr obj = ITestPtr( method () );
不过你的问题是在调用dll时,检查一下method的值吧。
要确保执行时你的dll与exe在同一目录。
[解决办法]
这个涉及到编译后的内容的组织方式,即ABI并不通用,尤其是涉及到C++的内容,通用的可能性非常小。
[解决办法]
通用的办法 就是 看下 WINDOWS+PE权威指南 这本书 了解下 PE结构
还有就是编译好的程序 用OD调试器 调试 虽然是在反汇编 查看问题比较容易
两个不同的编译器 调用 错误 不从汇编分析 查看堆栈 寄存器的数据变化 是分析不了问题的
那么些概念 有点太虚了 ,实际一点