使用 C++ 中的函数Delphi 中的 .DLL
我正在尝试从“近似最近邻居”(ANN)访问各种功能Delphi 中的库(实际上,它是 Lazarus/FreePascal,但这应该不重要)。
这是 C++ 中的减速:
#include <cstdlib> // C standard lib defs
#include <ANN/ANNx.h> // all ANN includes
#include <ANN/ANNperf.h> // ANN performance
using namespace std; // make std:: accessible
....
....
void annMaxPtsVisit( // set limit on max. pts to visit in search
int maxPts) // the limit
{
ANNmaxPtsVisited = maxPts;
}
这是我尝试从 Lazarus 中访问 annMaxPtsVisit 函数(如果你不知道 Lazarus 是什么,请假装它的 delphi):
unit unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure annMaxPtsVisit(input:Integer); stdcall;
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.annMaxPtsVisit(input: Integer); stdcall; external 'ANN.dll' name 'annMaxPtsVisit';
procedure TForm1.Button1Click(Sender: TObject);
begin
annMaxPtsVisit(10);
end;
end.
程序编译,但是当我尝试时执行它时,我收到一条错误消息:
“无法在动态链接库 ANN.dll 中找到过程入口点 annMaxPtsVisit”
如果有人可以帮助我有了这个我真的很感激。
以下是 DLL 的导出:
class ANNsampStat ann_average_err
class ANNsampStat ann_rank_err
const ANNbd_tree::`vftable'
const ANNbruteForce::`vftable'
const ANNkd_tree::`vftable'
const ANNpointSet::`vftable'
double * * __cdecl annAllocPts(int,int)
double * __cdecl annAllocPt(int,double)
double * __cdecl annCopyPt(int,double *)
double __cdecl annDist(int,double *,double *)
protected: void __thiscall ANNkd_tree::SkeletonTree(int,int,int,double * *,int *)
public: __thiscall ANNbd_tree::ANNbd_tree(class ANNbd_tree const &)
public: __thiscall ANNbd_tree::ANNbd_tree(class std::basic_istream<char,struct std::char_traits<char> > &)
public: __thiscall ANNbd_tree::ANNbd_tree(double * *,int,int,int,enum ANNsplitRule,enum ANNshrinkRule)
public: __thiscall ANNbd_tree::ANNbd_tree(int,int,int)
public: __thiscall ANNbruteForce::ANNbruteForce(class ANNbruteForce const &)
public: __thiscall ANNbruteForce::ANNbruteForce(double * *,int,int)
public: __thiscall ANNkd_tree::ANNkd_tree(class ANNkd_tree const &)
public: __thiscall ANNkd_tree::ANNkd_tree(class std::basic_istream<char,struct std::char_traits<char> > &)
public: __thiscall ANNkd_tree::ANNkd_tree(double * *,int,int,int,enum ANNsplitRule)
public: __thiscall ANNkd_tree::ANNkd_tree(int,int,int)
public: __thiscall ANNpointSet::ANNpointSet(class ANNpointSet const &)
public: __thiscall ANNpointSet::ANNpointSet(void)
public: __thiscall ANNsampStat::ANNsampStat(void)
public: class ANNbd_tree & __thiscall ANNbd_tree::operator=(class ANNbd_tree const &)
public: class ANNbruteForce & __thiscall ANNbruteForce::operator=(class ANNbruteForce const &)
public: class ANNkd_tree & __thiscall ANNkd_tree::operator=(class ANNkd_tree const &)
public: class ANNpointSet & __thiscall ANNpointSet::operator=(class ANNpointSet const &)
public: class ANNsampStat & __thiscall ANNsampStat::operator=(class ANNsampStat const &)
public: double __thiscall ANNsampStat::max(void)
public: double __thiscall ANNsampStat::mean(void)
public: double __thiscall ANNsampStat::min(void)
public: double __thiscall ANNsampStat::stdDev(void)
public: int __thiscall ANNsampStat::samples(void)
public: virtual __thiscall ANNbd_tree::~ANNbd_tree(void)
public: virtual __thiscall ANNbruteForce::~ANNbruteForce(void)
public: virtual __thiscall ANNkd_tree::~ANNkd_tree(void)
public: virtual __thiscall ANNpointSet::~ANNpointSet(void)
public: virtual double * * __thiscall ANNbruteForce::thePoints(void)
public: virtual double * * __thiscall ANNkd_tree::thePoints(void)
public: virtual int __thiscall ANNbruteForce::annkFRSearch(double *,double,int,int *,double *,double)
public: virtual int __thiscall ANNbruteForce::nPoints(void)
public: virtual int __thiscall ANNbruteForce::theDim(void)
public: virtual int __thiscall ANNkd_tree::annkFRSearch(double *,double,int,int *,double *,double)
public: virtual int __thiscall ANNkd_tree::nPoints(void)
public: virtual int __thiscall ANNkd_tree::theDim(void)
public: virtual void __thiscall ANNbruteForce::annkSearch(double *,int,int *,double *,double)
public: virtual void __thiscall ANNkd_tree::annkSearch(double *,int,int *,double *,double)
public: virtual void __thiscall ANNkd_tree::Dump(enum ANNbool,class std::basic_ostream<char,struct std::char_traits<char> > &)
public: virtual void __thiscall ANNkd_tree::getStats(class ANNkdStats &)
public: virtual void __thiscall ANNkd_tree::Print(enum ANNbool,class std::basic_ostream<char,struct std::char_traits<char> > &)
public: void __thiscall ANNkd_tree::`default constructor closure'(void)
public: void __thiscall ANNkd_tree::annkPriSearch(double *,int,int *,double *,double)
public: void __thiscall ANNsampStat::operator+=(double)
public: void __thiscall ANNsampStat::reset(void)
void __cdecl annClose(void)
void __cdecl annDeallocPt(double * &)
void __cdecl annDeallocPts(double * * &)
void __cdecl annMaxPtsVisit(int)
void __cdecl annPrintStats(enum ANNbool)
void __cdecl annResetCounts(void)
void __cdecl annResetStats(int)
void __cdecl annUpdateStats(void)
I am trying to access various functions from the 'Approximate nearest neighbor' (ANN) library from within Delphi (actually, it is Lazarus/FreePascal, but that shouldn't matter much).
Here is the deceleration in C++:
#include <cstdlib> // C standard lib defs
#include <ANN/ANNx.h> // all ANN includes
#include <ANN/ANNperf.h> // ANN performance
using namespace std; // make std:: accessible
....
....
void annMaxPtsVisit( // set limit on max. pts to visit in search
int maxPts) // the limit
{
ANNmaxPtsVisited = maxPts;
}
And here is my attempt to access the annMaxPtsVisit
function from within Lazarus (pretend its delphi if you don't know what Lazarus is):
unit unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure annMaxPtsVisit(input:Integer); stdcall;
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.annMaxPtsVisit(input: Integer); stdcall; external 'ANN.dll' name 'annMaxPtsVisit';
procedure TForm1.Button1Click(Sender: TObject);
begin
annMaxPtsVisit(10);
end;
end.
The program compiles, but when I attempt to execute it I get an error message:
"The procedure entry point annMaxPtsVisit could not be located in the dynamic link library ANN.dll"
If anyone could help me out with this I would really appreciate it.
Here are the exports from the DLL:
class ANNsampStat ann_average_err
class ANNsampStat ann_rank_err
const ANNbd_tree::`vftable'
const ANNbruteForce::`vftable'
const ANNkd_tree::`vftable'
const ANNpointSet::`vftable'
double * * __cdecl annAllocPts(int,int)
double * __cdecl annAllocPt(int,double)
double * __cdecl annCopyPt(int,double *)
double __cdecl annDist(int,double *,double *)
protected: void __thiscall ANNkd_tree::SkeletonTree(int,int,int,double * *,int *)
public: __thiscall ANNbd_tree::ANNbd_tree(class ANNbd_tree const &)
public: __thiscall ANNbd_tree::ANNbd_tree(class std::basic_istream<char,struct std::char_traits<char> > &)
public: __thiscall ANNbd_tree::ANNbd_tree(double * *,int,int,int,enum ANNsplitRule,enum ANNshrinkRule)
public: __thiscall ANNbd_tree::ANNbd_tree(int,int,int)
public: __thiscall ANNbruteForce::ANNbruteForce(class ANNbruteForce const &)
public: __thiscall ANNbruteForce::ANNbruteForce(double * *,int,int)
public: __thiscall ANNkd_tree::ANNkd_tree(class ANNkd_tree const &)
public: __thiscall ANNkd_tree::ANNkd_tree(class std::basic_istream<char,struct std::char_traits<char> > &)
public: __thiscall ANNkd_tree::ANNkd_tree(double * *,int,int,int,enum ANNsplitRule)
public: __thiscall ANNkd_tree::ANNkd_tree(int,int,int)
public: __thiscall ANNpointSet::ANNpointSet(class ANNpointSet const &)
public: __thiscall ANNpointSet::ANNpointSet(void)
public: __thiscall ANNsampStat::ANNsampStat(void)
public: class ANNbd_tree & __thiscall ANNbd_tree::operator=(class ANNbd_tree const &)
public: class ANNbruteForce & __thiscall ANNbruteForce::operator=(class ANNbruteForce const &)
public: class ANNkd_tree & __thiscall ANNkd_tree::operator=(class ANNkd_tree const &)
public: class ANNpointSet & __thiscall ANNpointSet::operator=(class ANNpointSet const &)
public: class ANNsampStat & __thiscall ANNsampStat::operator=(class ANNsampStat const &)
public: double __thiscall ANNsampStat::max(void)
public: double __thiscall ANNsampStat::mean(void)
public: double __thiscall ANNsampStat::min(void)
public: double __thiscall ANNsampStat::stdDev(void)
public: int __thiscall ANNsampStat::samples(void)
public: virtual __thiscall ANNbd_tree::~ANNbd_tree(void)
public: virtual __thiscall ANNbruteForce::~ANNbruteForce(void)
public: virtual __thiscall ANNkd_tree::~ANNkd_tree(void)
public: virtual __thiscall ANNpointSet::~ANNpointSet(void)
public: virtual double * * __thiscall ANNbruteForce::thePoints(void)
public: virtual double * * __thiscall ANNkd_tree::thePoints(void)
public: virtual int __thiscall ANNbruteForce::annkFRSearch(double *,double,int,int *,double *,double)
public: virtual int __thiscall ANNbruteForce::nPoints(void)
public: virtual int __thiscall ANNbruteForce::theDim(void)
public: virtual int __thiscall ANNkd_tree::annkFRSearch(double *,double,int,int *,double *,double)
public: virtual int __thiscall ANNkd_tree::nPoints(void)
public: virtual int __thiscall ANNkd_tree::theDim(void)
public: virtual void __thiscall ANNbruteForce::annkSearch(double *,int,int *,double *,double)
public: virtual void __thiscall ANNkd_tree::annkSearch(double *,int,int *,double *,double)
public: virtual void __thiscall ANNkd_tree::Dump(enum ANNbool,class std::basic_ostream<char,struct std::char_traits<char> > &)
public: virtual void __thiscall ANNkd_tree::getStats(class ANNkdStats &)
public: virtual void __thiscall ANNkd_tree::Print(enum ANNbool,class std::basic_ostream<char,struct std::char_traits<char> > &)
public: void __thiscall ANNkd_tree::`default constructor closure'(void)
public: void __thiscall ANNkd_tree::annkPriSearch(double *,int,int *,double *,double)
public: void __thiscall ANNsampStat::operator+=(double)
public: void __thiscall ANNsampStat::reset(void)
void __cdecl annClose(void)
void __cdecl annDeallocPt(double * &)
void __cdecl annDeallocPts(double * * &)
void __cdecl annMaxPtsVisit(int)
void __cdecl annPrintStats(enum ANNbool)
void __cdecl annResetCounts(void)
void __cdecl annResetStats(int)
void __cdecl annUpdateStats(void)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许按索引导入有效:(
这是通过 Dependecy Walker 获取的索引)
并且您可能必须更改为
cdecl
调用约定,具体取决于 DLL 的构建方式:编辑:查看添加的导出,看起来
cdecl
是正确的做法。Edit2:依赖关系遍历器还显示修饰名称,正如 @user786653 所怀疑的那样。这似乎也有效:
不过看起来很丑。
Maybe importing by index works:
(That's the index gotten via Dependecy Walker)
And you might have to change to
cdecl
calling convention, depending on how the DLL was built:Edit: Looks like
cdecl
is the right thing to do, looking at your added exports.Edit2: Dependency walker shows also the decorated names, as @user786653 suspected. This also seems to work:
Looks ugly, though.
首先将 annMaxPtsVisit 声明为普通过程,而不是 TForm1 方法:
First of all declare
annMaxPtsVisit
as ordinary procedure, not a TForm1 method: