【问题标题】:Builder C++ calling VC++ class生成器 C++ 调用 VC++ 类
【发布时间】:2012-10-18 21:24:27
【问题描述】:

我已经用 VC++ 编译了一个 Hunspell DLL,其中包含一个类... 现在我想在 Builder C++ 2006 中调用那个 DLL 来使用它的功能……我该怎么做呢?

我试过了:

typedef Hunspell * (CALLBACK *fpoint)(char *aff_file, char *dict_file);
fp pHunspell = (fp)GetProcAddress(handle_Hunspell, "hunspell_initialize");
if (pHunspell) {
  Hunspell* obj = (Hunspell *)pHunspell("..\hunspelldic\en_US.aff", "..\hunspelldic\en_US.dic");
  obj->add_dic("..\hunspelldic\it_IT.aff", "..\hunspelldic\it_IT.dic");
}

问题是,如果在 BuilderC++ 2006 中,我可以在 obj-> 之后按 shift-space 后显示函数,但看起来它并不能真正识别类函数,并且它一直发出 Unresolved external '__fastcall Hunspell::add_dic(.. .);'引用自...

将 VC++ dll 调用到 Builder C++ 中的确切方法是什么?在此先感谢大家...

干杯, 路易吉诺

【问题讨论】:

    标签: c++builder c++builder-2006


    【解决方案1】:

    首先你必须#include你的DLL的导入头文件(包括类,常量定义...)

    之后有两种方式:

    1. 静态 DLL 链接

      很简单,但有时不适用于 MSVC++ DLL。您需要为您的 DLL 添加一个 LIB 文件,您可以使用 Borland bin 文件夹中的 implib.exe 创建该文件,但您可能必须使用命令行切换以正确转换使用的修饰,直到构建器可以解析所有外部。例如:

      implib.exe -c -f -a glut32.lib glut32.dll 
      

      如果您的 lib 文件不正确,那么编译器将添加您未解决的外部错误。此外,来自 MSVC++obj/lib 文件与 Borland/Intel 不兼容,因为 MS 使用它们的非标准格式。在这种情况下,Borland 会喊出类似 wrong OMF 之类的东西,因此 implib 实用程序

    2. 动态 DLL 链接

      在下面的示例中,我从 DLL 链接了 2 个函数。对于链接类,您必须链接您导入的所有类的所有使用方法。此外,您可能会遇到 DLL 中的名称修改(类似于静态链接)的问题,因此 使用一些工具来探索 dll(我使用 DLL Export Viewer),它会向您展示真正的功能DLL 中的名称,您必须在 GetProcAddress 中使用。举个例子:

      HANDLE hdll;
      typedef BOOL(__stdcall *_InitRemoteCtrl)(HWND); _InitRemoteCtrl InitRemoteCtrl;
      typedef DWORD(__stdcall *_ReadRemoteData)();    _ReadRemoteData ReadRemoteData;
      
      __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
          {
          hdll=LoadLibrary("./RemtCtrl.dll");
          if (hdll==0) Application->Terminate();
          InitRemoteCtrl=(_InitRemoteCtrl)GetProcAddress(hdll,"InitRemoteCtrl");
          ReadRemoteData=(_ReadRemoteData)GetProcAddress(hdll,"ReadRemoteData");
          }
      
      void __fastcall TForm1::FormDestroy(TObject *Sender)
          {
          FreeLibrary(hdll);
          }
      

    如果可以,请使用第一个选项,因为它更安全。另外不要忘记导出/导入 DLL 头文件中的类以导出 DLL 源并导入以供 DLL 使用。

    class __declspec(dllimport/dllexport) myClass
        {
        ...
        };
    

    附言

    MSVC++Borland 之间构建 API 时要注意导出/导入的内容,避免使用未在展台中使用的非标准数据类型平台(或类似AnsiString,...)。

    【讨论】:

    • 我忘了提到 winapi 函数 GetProcAddress 有一些奇怪的错误,在某些情况下会导致 DLL 中的某些函数无法使用。
    • 这种奇怪的行为已经在 w2k sp4,wxp sp1,2,3 x32,w7sp1 x64 上进行了测试。在某些情况下,使 DLL 中的某些函数无法链接(找不到所需的函数,也找不到名称或序号)。这主要发生在 PE 编辑之后(重命名函数以匹配旧的 C 样式修改)。
    猜你喜欢
    • 1970-01-01
    • 2017-06-06
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多