从其它平台迁移而来
之前用lazarus
编写了使用IInterface
的dll
,可惜没有成功。当把IInterface
编译到exe
里时,功能正常,编译到dll
里再在exe
里调用就不正常,原因未深究,不过大致也知道是哪一类问题,至于还有没有其它问题,暂未可知。
闲来有空,有写了点Demo
来,有了不少新发现,在此记录下:
-
只有使用
exports
导出的函数才能在dll
外部调用 -
只有使用
stdcall
修饰的函数传参规则才与标准C
的传参规则相同,其它遵守标准C
传参规则的语言可以正常调用;否则,只有lazarus
编写的程序可以正常调用 -
入参为
string
类型时,无论是否使用stdcall
修饰,lazarus
编写的程序调用正常,其它语言未测试 -
返回值或出参为
string
类型时,调用报External: ACCESS VIOLATION
错误;但参数为PChar
时,调用正常 -
入参/出参/返回值为
结构体
时,调用正常 -
string
类型传参是指针/引用拷贝,结构体
传参是值拷贝 -
string
做入参时,由主调函数
分配内存并增加引用计数
,被调函数
执行时再次增加引用计数
,被调函数
结束时减少引用计数
,此时引用计数
不为0
不释放内存,主调函数
结束时再次减少引用计数
,引用计数
为0
释放内存,该内存由exe
分配,因此释放不报错;做出参时,由被调函数
执行时分配内存并增加引用计数
,被调函数
返回时先赋值给主调函数
的变量,增加引用计数
,再结束被调函数
,减少引用计数
,主调函数
结束时再次减少引用计数
,此时引用计数
为0
释放内存,但该内存是由dll
分配,因此产生External: ACCESS VIOLATION
错误 -
string
类型不适合在dll
和exe
之间传参(尤其是出参) -
返回值为
对象
时,调用异常;入参/出参为exe
创建的对象
时,调用正常
结论
根据测试得出的结论,可能不严谨:
-
指针
做为形参
(入参/出参
)传递没有问题,但必须遵守谁创建谁释放
的原则;指针
做为返回值
可能会有隐患 -
对象
传参实际传的是对象的指针
,规则与指针
相同 -
返回值
适合传递值拷贝
的类型,如整型
、浮点型
、布尔型
、结构体
、指针
(但指针
指向的内存要遵守谁创建谁释放
的原则,不过一般不直接使用)等 -
字符串
、结构体
的生命周期是由编译器维护的,使用需慎重