【问题标题】:Call C++ DLL in Delphi app在 Delphi 应用程序中调用 C++ DLL
【发布时间】:2011-10-21 09:29:12
【问题描述】:

我想在我的 Delphi 应用程序中调用 C++ DLL 的函数。
问题是我遇到了访问冲突。但不是在调用我的 C++ DLL 时,而是在我离开执行该操作的 Delphi 函数时。

错误消息(缩短):
在 0x7445c9f1 的访问冲突:从地址 0x00000000 读取。

我的 C++ 方法是这样的:

extern "C" __stdcall void SetName(LPCTSTR name) {strcpy_s(nameInDll,512,name);};

我的 Delphi 调用如下所示:

begin   
   ...
   hDll := LoadLibrary('myCpp.dll');
   SetName := getprocaddress(hDll, 'SetName');
   SetName(pchar(myControl.text));  //  <--- exception NOT here
   ...
end;  // <--- exception here

有趣的是,如果我像这样使用硬编码文本作为 DLL 调用的输入,它会起作用:

SetName(pchar('myName'));

编辑:
我错过了 C++ DLL 中的 __stdcall 定义。它是在宏中定义的。我更正了上面的 C++ 方法定义。

在看到这一点和您的提示后,我想出了一个可行的解决方案:

procedure SetName(s: PChar); stdcall; external 'myCpp.dll';

begin   
   ...
   SetName(pchar(myControl.text));
   ...
end;

【问题讨论】:

  • 试试 [this similiar thread][1],希望对您有所帮助。 [1]:stackoverflow.com/questions/1244441/…
  • 您需要出示SetName的声明。我敢打赌,您没有声明调用约定,或者声明了错误的调用约定。您的 C++ 方法很可能使用 cdecl

标签: c++ delphi dll


【解决方案1】:

听起来SetName 使用了错误的调用约定,请尝试使用cdecl;

类似这样的:

var
  SetName : procedure(nameArg: PChar); cdecl;

否则你的堆栈会被搞砸。

【讨论】:

    【解决方案2】:

    DLL 是为 Ansi 还是 Unicode 编译的?当 UNICODE 被定义时,LPCTSTR 映射到 wchar_t*,否则映射到 char*。这会影响您在 Delphi 中使用 DLL 的方式,其中 wchar_t* 等效于 PWideCharchar* 等效于 PAnsiChar 在 Delphi 中。

    【讨论】:

      【解决方案3】:

      根据您的工作量,您可能需要在编译器选项中设置:

      minimum enum size:  double word
      record field alignment:  quad word
      

      【讨论】:

      • 这些设置都与这个问题没有任何关系。没有枚举也没有记录。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 2018-09-07
      • 1970-01-01
      • 2020-07-03
      相关资源
      最近更新 更多