DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: 123glimmer
今日帖子: 20
在线用户: 10
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 dbyoung (dbyoung) ★☆☆☆☆ -
普通会员
2021/4/2 15:23:57
标题:
分享:在 Delphi 中,以不封装的模式直接调用 OpenCV C++ Class DLL 浏览:682
加入我的收藏
楼主: 花了两天时间,终于搞定了,
在 Delphi 中,以不封装的模式直接调用 OpenCV C++ Class DLL

地址:https://blog.csdn.net/dbyoung/article/details/115398764

感谢刘麻子的启发。
感谢武哥对函数调用约定的指点。
谢谢谢谢!

时间有限,只是简单的一个 DEMO。
以此为模板,应该很容易扩展。

有不对之处,还望高手指正。
此帖子包含附件:
PNG 图像
大小:173.9K
----------------------------------------------
武汉天气不好
作者:
男 glwang (glwang) ★☆☆☆☆ -
盒子活跃会员
2021/4/2 18:40:08
1楼: 楼主,能搞一个Delphi版安卓OpenCV吗?
----------------------------------------------
作者:
男 nevergrief (孤独骑士) ★☆☆☆☆ -
盒子活跃会员
2021/4/3 7:07:42
2楼: 这个方法真是叹为观止,堪称网上仅见。 这下DLL接口是不用翻译了,但使用的时候,数据类型还是要翻译的,是吧?

另外,  
c_BuildInfo: PChar   = '?getBuildInformation@cv@@YAABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ';

这里面有问号这样的特殊字符,能保证万无一失吗?这问号是真的问号,还是显示不出来?
----------------------------------------------
只有偏执狂才能生存!
作者:
男 142857 (142857) ★☆☆☆☆ -
盒子活跃会员
2021/4/3 7:15:13
3楼: 顶。。。。。。。。。
----------------------------------------------
dddddd
作者:
男 dbyoung (dbyoung) ★☆☆☆☆ -
普通会员
2021/4/4 0:56:33
4楼: @glwang:
  WINDOWS下,翻译 OpenCV 工作量是巨大的。
  我只是写了个简单的 DEMO,如果要实际用起来,估计还有一段路要走。
  所以最好的方法还是自己掌握了技术,按需翻译自己需要的部分。
  大而全的翻译,应该很难。OpenCV 太庞大了。
  我也是在空余时间捣鼓捣鼓。毕竟公司的活还是要干的。
  安卓下,应该不需要翻译吧。编译一下 OpenCV 源码,就可以得到 jar 文件了。
  而且 OpenCV 也可以编译为 JavaScript。

@孤独骑士: 
  数据类型肯定还是要翻译的。
  真的是问号。可以使用 depends 查看导出函数名称。
  也可以用 PBox 程序,程序员工具--->PE查看器,查看导出函数名称。
  我写时,是参看这个的。可以以 C 或 C++ 的方式查看导出函数名称。
  具体为什么是问号等等特殊字符,可以参考刘麻子的这篇文章:
  小技巧: Delphi创建/调用C++对象
----------------------------------------------
武汉天气不好
作者:
男 dbyoung (dbyoung) ★☆☆☆☆ -
普通会员
2021/4/4 17:05:26
5楼: 官网有现成的安卓版本:
  https://github.com/opencv/opencv/releases/download/4.5.2/opencv-4.5.2-android-sdk.zip
----------------------------------------------
武汉天气不好
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2021/4/4 22:17:16
6楼: C++编译器函数的重命名是有一套规则的,我觉得如果把规则复制下来,你可以做一个invoke函数,例如invoke('函数名',fastcall,[参数们])在invoke里面你把函数名转成C++的函数约定名字,再GetProcAddress调用起来方便不少。

另外看你里面有一套Delphi的字符串和VC的std::string的转换函数,我记得好像是从VC2002开始放弃字符串引用计数,所以高版本VC用你的函数还是挺好的,低版本会有内存问题。Linux的GCC到现在还是引用计数的方式。

还有让你写invoke函数是因为VC的成员函数如果不单独声明默认调用约定是微软私有的fastcall,Delphi这边没有对应的约定,invoke里面用RTTI把参数数组每个类型解析出来,然后内嵌汇编把参数按VC的fastcall组织起来,可以把一些细节隐藏起来。

不过这样的话有一些难度和工作量。
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 dbyoung (dbyoung) ★☆☆☆☆ -
普通会员
2021/4/5 11:17:38
7楼: 武哥一席话,够我理解一两天。

我理解的意思是:
  1、用内嵌汇编来统一处理对 VC 的成员函数 fastcall/thiscall 的调用。
   (这样能保证正确性。我用 FcvClassObj 应该有问题。也不灵活)
  2、用统一的函数模式 invoke 来封装函数调用,这样会减少一点工作量,有一定技术难度。
   (涉及 C++ 函数名字修饰符和 RTTI 的解析)

不知道我的理解对不对?

谢谢武哥指点。
----------------------------------------------
武汉天气不好
作者:
男 xjia (xjia) ★☆☆☆☆ -
盒子活跃会员
2021/4/5 15:44:47
8楼: 楼主利害,学习中
----------------------------------------------
-
作者:
男 dbyoung (dbyoung) ★☆☆☆☆ -
普通会员
2021/4/6 10:53:55
9楼: @xjia:
  不厉害。
  我的这个程序是碰巧。如果要具有通用性,要按照武哥说的方法来。
----------------------------------------------
武汉天气不好
作者:
男 taday (taday) ★☆☆☆☆ -
普通会员
2021/4/9 12:54:09
10楼: 测试中遇到一个奇怪的问题 
ttt.imread('C:\Windows\Web\Wallpaper\Windows\img0.jpg', Integer(IMREAD_GRAYSCALE)); // 读取图片
 原始的运行没有问题,现在把img0.jpg 拷贝到D盘,用下面的语句运行。opencv 部分会报错 
ttt.imread('D:\img0.jpg', Integer(IMREAD_GRAYSCALE)); 

发现和图像名的字符串长度有关系,只要长度够长,程序就能运行。如果短程序就报错
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行54.6875毫秒 RSS