spiderman's 点滴(1)
来源:互联网 发布:java object() 编辑:程序博客网 时间:2024/05/18 13:24
从dll中加载函数, 惨痛的教训啊, 还差点去问别人, 是不是你的DLL弄错了
-----------------------------------------------------------------------------
使用Win32::API时需要注意的基本上就3点:
1、DLL中函数的calling convention必须为__stdcall型。这个应该是Win32::API的底层库中引入的一个假设,和Perl没关系;如果你用XS自己写DLL的调用过程,自然可以根据DLL中特定的calling convention自行调整调用方法,这一限制也就不复存在了。
2、导入DLL中的函数时要保证函数标识符的正确性。之所以要提这一点是因为在不使用definition file的情况下,不同的编译器在产生DLL时对导出函数名的处理方法不一样。以VC6为例,当调用规范为__cdecl时,函数func将被改名为_func;调用规范为__stdcall时,函数func被改名为_func@n,其中n是函数参数的总字节数。因此在导入函数之前最好用dumpbin之类的工具看一下DLL导出函数的真正标识符,必须用这种name mangling之后的标识符才能正常导入函数。为了避免这种麻烦,在写DLL的时候尽量用definition file指定每个函数生成的标识符吧。
3、用给出函数原型的方法导入函数时表示指针的*号一定要和类型紧挨着,另外这时对于指针类型的参数不需要自己pack数据了。例如:
假设test.dll中有一个函数long func(long *a),则
use Win32::API;
$handle=Win32::API->new('test','long func(long* a)'); # 这里指针符号*和指向的类型必须紧挨着,
# 这是由Win32::API解析原型的方法决定的。
$a=10; # 注意:不需要pack了!Win32::API会自动根据函数原型pack数据
$handle->Call($a);
不使用原型时,由于指针指向的对象类型未知,Win32::API无法知道如何处理这种数据,就必须手工将数据pack到标量中去。
$handle=Win32::API->new('test','func','P','N');
$a=pack('L',10);
$handle->Call($a); 【网摘】
--------------------------------------------------------------------
对以上3点中的第2点, 我刻骨铭心啊, 以后不敢弱弱的直接拿函数名去getprocaddress了, 其余两点等撞墙后顿悟。
补充:
dumpbin -export xxxx.dll > xxxx.def
- spiderman's 点滴(1)
- spiderman's 点滴(2)
- HOJ 2139 Spiderman's workout(动态规划)
- Spiderman’s workout (dynamic programming)
- POJ 3003 Spiderman’s workout
- poj1925--Spiderman(dp)
- 【POJ 1925】 Spiderman(dp)
- POJ 1925 Spiderman (DP)
- (中等)动态规划Hoj 1719 Spiderman
- POJ 1925 Spiderman(线性dp)
- Spiderman源码分析(三)Fetcher
- Spiderman源码分析(四)Frontier
- Spiderman源码分析(五)Parser
- 点滴(1)
- Spiderman源码分析(一)加载和初始化
- Spiderman源码分析(二)调度和执行
- 【poj 1925】Spiderman 题意&题解&代码(C++)
- 2397 Spiderman
- 驱动开发1:介绍驱动
- 我不会OOO,仍然可以XXX
- 自己动手做网线
- HTTP 500 - 内部服务器错误 之三步解决方案
- 当下10大最热门的网站开发技术
- spiderman's 点滴(1)
- lfs我来了..
- 三十而立
- linux下IPTABLES配置详解
- 美国人找工作怪招迭出 跟贵人搭讪办就业派对
- 加载图片覆盖整个窗口
- 详细介绍五种JSP跳转方法
- 手把手教你把Vim改装成一个IDE编程环境(图文)
- many to one FK更新問題求解(identifier of an instance)