2010-10-29 76 views
3

有这个伟大的开源OCR组件,谷歌一直在发展: http://code.google.com/p/tesseract-ocr/德尔福/ Tesseract OCR:有人可以帮助我得到这个新的DLL在德尔福工作?

他们有一个新的版本出来(第3版)于2010年10月

的开始,但这个新版本不再有一个工作的C包装,这取决于Delphi社区中的某个人从Delphi内部工作 - 我试图做到这一点,因为我非常需要它,没有其他人急于做,但我有当涉及到DLL并将C转换为Delphi时,不知道我在做什么。那是我可以使用你的帮助的地方。

我选择的线索是我需要Dependency Walker以某种方式防止'name-mangling'(不知道这意味着什么)。 实际的DLL API方法在C文件中 - 大概是您在Dependency-Walker中看到的DLL函数名称将与API文件中的函数相匹配。

下面是您需要帮助的所有内容: 您需要一个带有tessdll.dll的文件夹,而leptonlib.dll也需要在那里。您需要一个名为'tessdata'的子文件夹,并且该文件夹内部将是您的'语言数据文件' - [检查网站上的下载页面]

这里是Windows安装程序,以便您可以在动作中看到DLL : [检查网站上的下载页面]

为了让Delphi在Delphi中能够正常工作,您需要将可执行文件放在与DLL相同的文件夹中。 然后您需要知道在DLL中调用什么,并且您可以查看C源文件: [检查站点上的下载页面上的源文件]

感谢您的任何帮助。

回答

6

从第一次看,这可能是困难的。由于API是以C++类的形式显式封装的,所以唯一干净的方法就是执行它:

在C中实现一个封装器DLL,公开类的平面化接口,以便您可以编写一个Delphi单元来使用它。

原理这里概述:

http://rvelthuis.de/articles/articles-cppobjs.html

直接使用C++ API将需要一些聪明的黑客汇编。这不仅仅是名称在这里成为问题,而且也是用于创建DLL(即Visual Studio 2008 Express)的C++编译器的调用约定。

所以有人必须首先使用Visual C++ 2008 Express编写一个带有C API的DLL。

一些澄清concering您的意见:

当你想使用你的应用程序,你需要知道你需要什么样导入符号的外部库。

正常的符号是kernel32.dll中的'SetDllDirectory'。在Delphi中导入没有问题,但是C++通常使用更人为的方式来命名它的符号。一个例子是'_ZN·9wikipedia·7Article·6format·E'(摘自本文:http://en.wikipedia.org/wiki/Name_mangling

尽管可以导入一个只是问题的一小部分的损坏符号。

您可以告诉C++编译器不要使用使用extern "C" {指令的名称修改。

目前还有至少另外两个问题:

  • 你没有方法来确定C的大小++德尔福对象实例
  • 一个C的所有方法++对象采取隐藏this说法(像Delphi中的Self)

这些问题可以通过编写一个类似Rudy的文章中所述的包装来绕开。

你必须写一个简单的C++动态链接库导出一个普通的C API(不包括重整,并与正常的C函数),在伪代码看起来像:

extern "C" { 

void* MakeAnInstanceOfDesiredClass(void) 
{ 
    return new DesiredClass(); 
} 

void DestroyInstanceOfDesiredClass(void* instance) 
{ 
    delete instance; 
} 

int SomeMethodOfDesiredClass(void* instance) 
{ 
    return reinterpret_cast<DesiredClass*>(instance)->SomeMethod(); 
} 

} 

我会试试看,但是我的网络连接速度很慢,我没有Visual Studio在这里,对不起。

+0

谢谢你的回答,它的确有一些亮点。不过,我还是很困惑。我已经下载了Visual C++ 2010,因为我非常渴望得到版本3--所以我不妨试试它自己 - 但我对此一无所知,仍然非常困惑。就像,C,C++中的源代码是什么?我可以从Visual C++ 2010编译两种语言吗?有一个可以下载的DLL的“Windows DLL”版本 - 当然,这就是所有的Delphi需求? ...所以,从你所说的话,我不可能把自己当作一个卑微的Delphi程序员。 – 2010-10-29 17:19:04

+0

另外,什么是'名称捣毁'? – 2010-10-29 17:28:00

+0

Dll从未设计用于导出对象方法。名称修改通过使用特殊格式的函数名称来解决此问题。不同语言的编码技术细节各不相同(甚至一个编译器制造商到另一个编译器制造商)Delphi使用bpl格式(这是一个dll下的dll)中的名称转换。 – 2010-10-29 17:50:25

2

实际上是在文档左看右看之后可能会有的功能子集,它仍然是C API,从而直接访问德尔福:

BOOL APIENTRY DllMain (HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 
TESSDLL_API void __cdecl TessDllRelease() 
TESSDLL_API void *__cdecl TessDllInit (const char *lang) 
TESSDLL_API int __cdecl TessDllBeginPageBPP (uinT32 xsize, uinT32 ysize, unsigned char *buf, uinT8 bpp) 
TESSDLL_API int __cdecl TessDllBeginPageLangBPP (uinT32 xsize, uinT32 ysize, unsigned char *buf, const char *lang, uinT8 bpp) 
TESSDLL_API int __cdecl TessDllBeginPageUprightBPP (uinT32 xsize, uinT32 ysize, unsigned char *buf, const char *lang, uinT8 bpp) 
TESSDLL_API int __cdecl TessDllBeginPage (uinT32 xsize, uinT32 ysize, unsigned char *buf) 
TESSDLL_API int __cdecl TessDllBeginPageLang (uinT32 xsize, uinT32 ysize, unsigned char *buf, const char *lang) 
TESSDLL_API int __cdecl TessDllBeginPageUpright (uinT32 xsize, uinT32 ysize, unsigned char *buf, const char *lang) 
TESSDLL_API void __cdecl TessDllEndPage (void) 
TESSDLL_API ETEXT_DESC *__cdecl TessDllRecognize_a_Block (uinT32 left, uinT32 right, uinT32 top, uinT32 bottom) 
TESSDLL_API ETEXT_DESC *__cdecl TessDllRecognize_all_Words (void) 
TESSDLL_API void __cdecl ReleaseRecognize() 
TESSDLL_API void *__cdecl InitRecognize() 
TESSDLL_API int __cdecl CreateRecognize (uinT32 xsize, uinT32 ysize, unsigned char *buf) 
TESSDLL_API ETEXT_DESC *__cdecl reconize_a_word (uinT32 left, uinT32 right, uinT32 top, uinT32 bottom) 

我不知道这些功能是不够的,但它们可以直接访问。

+0

实际上我相信这些函数是用于最新版本2.04的包装,并且在这个新版本3.0中进行了描述。在网站的问题页面上打开了一个问题,并且必须为3.0版编写一个新的C封装器。 – 2010-10-29 19:18:03

1

转换Jens引用的代码不应该太难。您可以尝试一些C到德尔福转换器(http://www.drbob42.com/delphi/headconv.htm,http://cc.embarcadero.com/item/26951)。请注意,他们只能转换60-80%的代码,因此需要进行手动工作。如果你仍然坚持这一切,然后搜索标题的VB转换是否存在。从C转换起来会容易得多,特别是因为VB2Delphi转换器可以在没有手动工作的情况下执行此操作(http://www.marcocantu.com/tools/vb2delphi.htm)。