我在Visual Studio中编译了一个DLL(源代码是用C++编写的,我几乎不懂).这是一块Scraper.h:
struct SWin { char title[512]; HWND hwnd; }; SCRAPER_API bool ScraperGetWinList(SWin winList[100]);
现在我正在尝试在我的Delphi应用程序中使用上面的函数:
type tWin = record title: String; hwnd: HWND; end; function ScraperGetWinList(var WinList: Array of tWin): Boolean; external 'Scraper.dll'; var myWinList: Array [1..100] of tWin; procedure TMainForm.GetWinListButtonClick(Sender: TObject); begin ScraperGetWinList(myWinList); ...
该项目无法编译,我收到以下消息:无法在动态链接库中找到过程入口点ScraperGetWinList:Scraper.dll.
我究竟做错了什么?
根据我的Linux经验,我会说你遇到了所谓的" 名称错误 "问题.您的过程的入口点不称为"ScraperGetWinList",而是类似"_ZN18ScraperGetWinListEpN4SWin".
问题是,与C语言不同,在C++语言中,入口点的名称与函数名称不同.难怪:假设你有一组重载函数; 它们应该在您的DLL中有不同的入口点.这就是名称改变发挥作用的地方.
这个问题最常见的解决方案是以一种使用C调用约定的方式定义库的接口.然后,接口函数不会发生名称错位.
请注意,您不必在C中编写整个库,您只应为它们声明函数以发出类似C的入口点.
通常它是这样写的:
extern "C" { SCRAPER_API bool ScraperGetWinList(SWin winList[100]); // More functions }
重新编译您的库并在Delphi中使用它没有问题.
注意,您还应该调整它们的调用约定(stdcall或cdecl)以匹配C++头和Delphi代码.但是,这在另一个问题中得到了最好的解释.