首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

如何调用第三方DLL导出的Interface

2013-07-01 
怎么调用第三方DLL导出的Interface?我想在C++中使用Delphi开发的DLL导出的接口实现Delphi DLLlibrary Proj

怎么调用第三方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调试器 调试 虽然是在反汇编 查看问题比较容易
两个不同的编译器 调用 错误 不从汇编分析 查看堆栈 寄存器的数据变化 是分析不了问题的
那么些概念 有点太虚了 ,实际一点

热点排行