偶要用delphi写几个dll来公开发布出去,让其他工具的程序员调用。应该注意些什么事项啊?请有经验的大侠来指点几句,感谢不尽!(300分)

  • 主题发起人 主题发起人 shangshang
  • 开始时间 开始时间
S

shangshang

Unregistered / Unconfirmed
GUEST, unregistred user!
主要是接口声明,接口参数的数据类型,回调的方式等。

偶会用stdcall,
偶会全部用pchar不用string,
偶目前没有什么特别的数据类型,
不过可能会有些比如含些基本数据类型的packed record ;
偶目前用的异步通知客户端的方式使用sendmessage.自定义消息,合适吗? 回调函数的方式,我不熟悉其他语言的书写方式,不知怎么样实现。

仅此,不知道还需要注意什么,请有经验的大侠来指点几句,感谢不尽!
 
现在我也正向大虾请教学习中。。。
留个足迹,关注一下
 
消息要用 SendMessage 发.

如果要把一个结构体 SendMessage 出去. 最后用 GlobalAlloc 得到的内存地址.

用 Getmem 或 LocalAlloc 的对方可能会不能访问.

SendMessage 会等对方处理完后才返回.

你 DLL SendMessage 之后就可以把结构体 Free 了.
(还有就是告诉开始人员,如果要保存结构体,请自行处理 , [一般开发人员都知道的])

个人认为就用消息好了.

回调函数只能传入全局函数做为参数. 在 OOP 中.用处是不是很明显.
如都在 Win平台.问题不大.
只是 VB 可能不能处理消息.
 
vb不能处理消息?
如果用sendmessage ,自己不能用new来分配结构体指针的内存吗?
不是都在一个内存空间吗?

我的目的是希望能尽量的模拟win32 api的声明和设计参数的方式,
不知道是否delphi做出的dll和他一样好被用。

谢谢。
 
关于内存那个只是我猜的.


VB 不能处理 SendMessage 发送过去的消息.
(当然也不是说完全不能.有高手可以用 GetWindowProc 的方法来用自己的 WndProc 来替代原窗口过程,但对应一般人员,这种方法难度大了点)

如果很在意这个问题,那只有用回调函数了.
参考一下 API CreateThread 就明白了如做定义了.
 
用PChar的时候,如果有写入字符到PChar里面的时候,一定要做边界检查,防止越界异常,或避免溢出漏洞。
 
zqw0117,谢谢大侠
通常怎么检查呢? 像某些api一样,再传入一个类似缓冲区长度的参数吗?,还是自己内部检测StrLen是否有效值即可啊?
 
不管传入还是传出,都应该做好检查。还有,如果你的PChar是输出值(就是dll写入让主程序读这个PChar的话),分配PChar空间和释放PChar占用的内存,应该由主程序负责,dll不参与内存分配。
 
各位老大真是太厉害了,小弟是新手,以后多指教!
 
DLL里面有窗口吗?有的话别忘了传句柄进来哦。
 
用DLL是代码保密的需要吗?
 
DLL无form,不过有wndproc ,呵呵。

是不是上面说的就足以写一个好用的dll呢,呵呵,各位有写过让人家比如vc,vb什么的调用的吗?
 
1.传递参数的时候如果觉得PCahr不方便,可以引入FastMem单元(delphibox有下载),就可以使用string传递参数啦.
2.如果想在dll中调用dll,注意结束的时候释放被调用dll.
 
dll等于是我们对外提供的sdk的内容。没什么需要保密的,通信协议都是开放的,怕用户不会开发,或者嫌从协议开发太慢太麻烦才想给人家dll的,只要引出几个函数,这些函数封装我们的通信协议了。这样客户会更乐意接受些
 
dll感觉就是不怎么得心应手啊,控制上感觉麻烦!
 
请 继续下去,近日结贴
 
前两天才帮别人解决一个关于DELPH编写DLL,VC调用出错的问题下面是我写的文章

VC里调用DELPHI编写的DLL要注意的!


今天在DFW上面看见有一个贴子是关于VC里面调用DELPHI编写的DLL,对于VC和DELPHI有一定自信的我,当然不过这样的拿分机会了。

贴子的大概内容是这样的,在DELPHI定义了这样一个函数并输出
myfunc(i:Integer
b:Byte
var Buffer:array of Word): Boolean
stdcall;

之后在VC里面定义函数类型
typedef BOOL (__stdcall *pMyfunc)(int, BYTE, WORD*);

调用代码是这样
HMODULE h= LoadLibrary("C://Program Files//Borland//Delphi7//Projects//project2.dll");
pMyfunc MyFunc=(pMyfunc)GetProcAddress(h,"myfunc");
WORD a[100];
memset(a, 0, sizeof(a));
a[0]= 1;
a[1]= 2;
a[2]= 3;
MyFunc(1, 2, a);

但是函数成功返回后却提示:
The value of ESP was not properly saved across a function call.This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

经过研究,得出的解决的办法就是在VC里面这样定义函数类型
typedef BOOL (__stdcall *pMyfunc)(int, BYTE, WORD*, int);
多出一个参数int是数组的大小,所以调用时就要指出数组的大小
MyFunc(1, 2, a, sizeof(a)/sizeof(WROD));


下面是研究的过程。

根据出错提示和我的破解来看,一定是调用函数后栈不平衡了。至于具体原因就要再进一步研究。

我在Delphi调用了这个函数,并没有任何问题。所以我的直觉告诉我,一定和那个数组有关,之后我拿掉那个数组参数,在VC里调用一次,结果一切正常! 看来真的是数组参数的问题。但是为什么Delph里调用却没有问题呢?想来想去也想不出原因,看来只好在汇编里找答案了。在Delphi里调用myfunc的地方下了断点,

{调用函数的代码}
var
aw: array[0..99] of word;
//aw: array of word;
begin
//setlength(aw, 101);
myfunc(1, 2, aw);

//这里的反汇编对应静态数组的代码
004081FA 6A63 push $63
004081FC 6898A74000 push $0040a798
00408201 6A02 push $02
00408203 6A01 push $01
00408205 E82EFFFFFF call myfunc
//这里的反汇编对应动态数组的代码
004086E4 A198A74000 mov eax,[aw]
004086E9 E812BCFFFF call @DynArrayHigh
004086EE 50 push eax
004086EF A198A74000 mov eax,[aw]
004086F4 50 push eax
004086F5 6A02 push $02
004086F7 6A01 push $01
004086F9 E8E6FEFFFF call myfunc
可以很清楚的看到,我们的函数明明只定义了3个参数,却push了4个参数!而第4个函数根据静态数组的反汇编可以看出就是数组的长度!

所以在VC的函数定义要多定义一个参数,并把数组的长度传递给函数调用才会正常!

反思:原来自己对DELPHI的内部还不是很了解,还是菜菜一名,呵呵。

说到尾就是,你在DELPHI输出一个数组引用的参数的函数,在VC里定义里要在这个函数的数组引用参数后面多加一个int类型的参数!
 
Writer 大侠,你若是菜菜鸟, 偶们就要全体失业了。。。。。[:(]
vc,delphi,汇编都熟悉,呵呵。
谢谢大侠共享经验,我会避免这个问题,以及向大侠学习你的解决问题的方法。呵呵
 
结了啦。如果哪位大侠还有建议,一定再有感谢。谢谢上面各位支持。
 
后退
顶部