关于dll使用“在静态库中使用 MFC”出现的问题,请教大神

jianzhanger 2013-05-27 08:03:36
此前编写了一个dll,导出了一些常用函数和类,使用了在“共享 DLL 中使用 MFC”,一切运转良好。
现在因为项目需要,要把此设置改为“在静态库中使用 MFC”,问题来了:

1.凡是使用了Function(CStringArray& ary)形式的函数,都出现了“其原因可能是堆被损坏,这也说明程序或它所加载的任何 DLL 中有bug”
个人觉得可能是使用静态链接后,exe和dll有各自的内存分配,这种情况该怎么解决呢。
目前使用了CStringArray* Function()的形式返回结果,可以解决问题,但是觉得不爽

2.Function(CStringArray& ary1,CStringArray& ary2)这种形式的函数该怎么处理呢

3.部分类导出后,出现很多问题,有没有大神有这方面的经验。

4.分不够可以加。
...全文
305 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
jianzhanger 2013-06-06
  • 打赏
  • 举报
回复
没什么好办法,就这样吧
jianzhanger 2013-05-30
  • 打赏
  • 举报
回复
那我怎么才能实现在win7编译的产品,能在win2003下运行呢?
jianzhanger 2013-05-30
  • 打赏
  • 举报
回复
引用 10 楼 redui 的回复:
MFC天生就应该用动态库形式来使用,它就不是用于静态链接的主,如果你只有一个EXE使用了静态链接MFC,而没有任何别的DLL,看起来还会正常,其它情况下一定会把你颠得七晕八素,死了都不知道是从哪个坑里摔下来的。
好吧。我认输了。
flyound 2013-05-30
  • 打赏
  • 举报
回复
引用 8 楼 jianzhanger 的回复:
返回指针是可以解决。但是需要在dll里new,在exe里delete。觉得不是很好。能不能实现在exe的new和delete。另外能不能直接在参数里返回。
这个可以啊,你再到出库里提供一个借口用于指针的内存释放,比如 void DeleteMemory(void * pMem) { delete pMem; } 或者如果是是导出的类什么的,直接在该类写一个静态函数用于释放内存。
schlafenhamster 2013-05-28
  • 打赏
  • 举报
回复
"凡是使用了Function(CStringArray& ary)形式的函数" 你还是 传递的指针,不要 那个 & 。 Function(CStringArray ary) 试试 ?(因为是 Array,不一定行)
jianzhanger 2013-05-28
  • 打赏
  • 举报
回复
引用 7 楼 flyound 的回复:
你这个最好的方式还是采用返回指针的方式,Dll导出函数或者类的时候,一定要主要内存申请和释放的问题,你现在的问题主要是你的dll版本是采用静态链接方式,如果对方运行MFC版本跟你编译的不一样,而传入的内存是采用对方版本生成的内存布局,而你dll采用的是自己编译时的内存布局,这样交叉使用就会出问题了。还有要注意下debug和release版本匹配的问题。
引用 7 楼 flyound 的回复:
你这个最好的方式还是采用返回指针的方式,Dll导出函数或者类的时候,一定要主要内存申请和释放的问题,你现在的问题主要是你的dll版本是采用静态链接方式,如果对方运行MFC版本跟你编译的不一样,而传入的内存是采用对方版本生成的内存布局,而你dll采用的是自己编译时的内存布局,这样交叉使用就会出问题了。还有要注意下debug和release版本匹配的问题。
返回指针是可以解决。但是需要在dll里new,在exe里delete。觉得不是很好。能不能实现在exe的new和delete。另外能不能直接在参数里返回。
flyound 2013-05-28
  • 打赏
  • 举报
回复
你这个最好的方式还是采用返回指针的方式,Dll导出函数或者类的时候,一定要主要内存申请和释放的问题,你现在的问题主要是你的dll版本是采用静态链接方式,如果对方运行MFC版本跟你编译的不一样,而传入的内存是采用对方版本生成的内存布局,而你dll采用的是自己编译时的内存布局,这样交叉使用就会出问题了。还有要注意下debug和release版本匹配的问题。
jianzhanger 2013-05-28
  • 打赏
  • 举报
回复
引用 3 楼 oyljerry 的回复:
用void*等做参数,然后再处理的时候转换
有例子吗?大版主
jianzhanger 2013-05-28
  • 打赏
  • 举报
回复
引用 2 楼 combobox2013 的回复:
[quote=引用 1 楼 akirya 的回复:] 1 用动态连接dll,要么使用API分配内存,CString之类的就用不了了 2 3 珍惜生命,远离导出类。坑太多,不然也不会有COM这玩意出现。 真想用导出类的话,那就用COM。
目测原因: cString ,CstringArray这种类型,在以下情况下出 2个条件: 1. 一个是静态,一个是共享mfc dll 2. Cstring在调用模块中定义后,然后做参数,进入dll,那么dll函数内部不小心释放了Cstring的缓冲区,即: 对Cstring的缓冲区就行释放内存,那么就会有问题。 如何想避免; 那么把 条件1改成 两个都是共享的。 [/quote] 目前CString在函数导出时,暂未发现问题,类导出时,保险期间改成了LPCTSTR
jianzhanger 2013-05-28
  • 打赏
  • 举报
回复
引用 1 楼 akirya 的回复:
1 用动态连接dll,要么使用API分配内存,CString之类的就用不了了 2 3 珍惜生命,远离导出类。坑太多,不然也不会有COM这玩意出现。 真想用导出类的话,那就用COM。
确实坑,当时的想法是重用一些代码,用最简单的方式,后面的剧情不受控制了。
redui 2013-05-28
  • 打赏
  • 举报
回复
MFC天生就应该用动态库形式来使用,它就不是用于静态链接的主,如果你只有一个EXE使用了静态链接MFC,而没有任何别的DLL,看起来还会正常,其它情况下一定会把你颠得七晕八素,死了都不知道是从哪个坑里摔下来的。
oyljerry 2013-05-27
  • 打赏
  • 举报
回复
用void*等做参数,然后再处理的时候转换
combobox2013 2013-05-27
  • 打赏
  • 举报
回复
引用 1 楼 akirya 的回复:
1 用动态连接dll,要么使用API分配内存,CString之类的就用不了了 2 3 珍惜生命,远离导出类。坑太多,不然也不会有COM这玩意出现。 真想用导出类的话,那就用COM。
目测原因: cString ,CstringArray这种类型,在以下情况下出 2个条件: 1. 一个是静态,一个是共享mfc dll 2. Cstring在调用模块中定义后,然后做参数,进入dll,那么dll函数内部不小心释放了Cstring的缓冲区,即: 对Cstring的缓冲区就行释放内存,那么就会有问题。 如何想避免; 那么把 条件1改成 两个都是共享的。
  • 打赏
  • 举报
回复
1 用动态连接dll,要么使用API分配内存,CString之类的就用不了了 2 3 珍惜生命,远离导出类。坑太多,不然也不会有COM这玩意出现。 真想用导出类的话,那就用COM。

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧