Delphi / Tesseract OCR:有人可以帮我在Delphi中使用这个新的DLL吗?

时间:2010-10-29 15:11:23

标签: delphi dll ocr tesseract

谷歌一直在开发这个伟大的开源OCR组件: http://code.google.com/p/tesseract-ocr/

他们在2010年10月初推出了新版本(第3版)。

但是这个新版本不再有一个可用的C包装器,并且Delphi社区中的某个人可以从Delphi内部工作 - 我正在尝试这样做,因为我非常需要它而没有其他人是急着做但我不知道我在做DLL和将C转换为Delphi时做了什么。这就是我可以帮助你的地方。

我所接受的线索是,我需要Dependency Walker以某种方式防止'名称错误'(不知道这意味着什么)。 实际的DLL API方法在C文件中 - 可能是你在Dependency-Walker中看到的DLL函数名称将匹配API文件中的函数。

以下是您需要提供的所有帮助: 你需要一个包含tessdll.dll的文件夹,leptonlib.dll也需要在那里。你需要一个名为'tessdata'的子文件夹,在文件夹里面将是你的'语言数据文件' - [查看网站上的下载页面]

这是Windows安装程序,因此您可以看到DLL正在运行: [查看网站上的下载页面]

要使这个适用于Delphi,您可以将您的可执行文件放在与DLL相同的文件夹中。 然后,您需要知道DLL中要调用的内容,为此您可以查看C源文件: [检查网站上下载页面上的源文件]

感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

从第一眼看,这可能很难。由于API显然封装在C ++类中,唯一干净的方法是:

在C中实现一个包装器DLL,它暴露了类的flattented接口,这样你就可以编写一个Delphi单元来使用它。

这里概述了原则:

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

直接使用C ++ API需要一些聪明的汇编程序黑客攻击。这里不仅有名称修改问题,而且还有用于创建DLL(即Visual Studio 2008 Express)的C ++编译器的调用约定。

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

一些澄清来表达您的意见:

如果要在应用程序中使用外部库,则需要知道需要导入哪些符号。

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

虽然可以导入一个受损的符号,但这只是问题的一小部分。

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

至少还有两个问题:

  • 您没有从Delphi
  • 确定C ++对象实例大小的方法
  • C ++对象的所有方法都采用隐藏的this参数(如Delphi中的Self)

这些问题可以通过编写Rudy的文章中解释的包装来避免。

你必须编写一个简单的C ++ Dll,它导出一个普通的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,抱歉。

答案 1 :(得分:2)

实际上在仔细查看文档之后,可能还有一部分函数仍然是C API,因此可以直接从Delphi访问:

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) 

我不知道这些功能是否足够,但可以直接访问。

答案 2 :(得分:1)

转换Jens引用的代码不应该太难。您可以尝试一些C到Delphi转换器(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)。