谷歌一直在开发这个伟大的开源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源文件: [检查网站上下载页面上的源文件]
感谢您的帮助。
答案 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" {
指令进行名称修改。
至少还有两个问题:
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)。