抓狂得菜鸟 我与DLL不得不说的事

n27741 2007-06-22 11:21:06
我真傻 真的。我单知道DLL可以封装方法,可以动态调用
但是我没有顾虑到DLL的通用性和dll与宿主EXE处于不同的进程空间

我后悔不该让DLL与exe共用一个VCL组件的对象
结果就是不得不带一堆bpl和borlndmm.dll 以及cc3260.dll

还提心吊胆的提醒别人怎么用。。。。

我要问的问题有2个
1 dll到底该怎么用 里面纯粹就是句柄和C标准的变量?如何设计一个DLL?

2 如果宿主程序使用到了DLL里面new出来的一个控件,那么怎么做才能不带包编译就可以发布????
...全文
538 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
kinglh 2007-07-04
  • 打赏
  • 举报
回复
学习
前段时间也想在DLL里生成一个VCL控件,再传给EXE,但没有想到方法
呵呵学习!
n27741 2007-07-04
  • 打赏
  • 举报
回复
我现在的态度是 这个设计方案是错误
daydayup234 2007-07-04
  • 打赏
  • 举报
回复
你是党员吧?
标题党的!
cczlp 2007-06-29
  • 打赏
  • 举报
回复
那么 不带rtl包的时候,为什么通过句柄 不能用findcontrol返回 共享控件的指针?
=============================================================================
也许是FindControl本身的限制,只知道用在线程中会有问题, 有时间研究一下.

不同进程难道就不能互相访问内存?
================================
正常是这样的, 这是系统的安全所在. 但可以通过OpenProcess等非常手段读写.
在32位系统上, 每个进程有独立的4G地址空间, 进程用到的所有DLL都映射到这个4G空间.
n27741 2007-06-29
  • 打赏
  • 举报
回复
不同进程难道就不能"直接"互相访问内存?
看漏掉了...


n27741 2007-06-29
  • 打赏
  • 举报
回复
cczlp(不惑)说的很对,dll和exe在同一地址空间,可以共享所有的资源,内存相互可以直接访问

但是我没有顾虑到DLL的通用性和dll与宿主EXE处于不同的进程空间
============================================================
Dll和宿主Exe肯定在同一个进程空间

那么 不带rtl包的时候,为什么通过句柄 不能用findcontrol返回 共享控件的指针?

rtl包到底干了什么?

又为什么用 API函数可以通过句柄对控件做一切操作?

不同进程难道就不能互相访问内存?

还请赐教


Y___Y 2007-06-28
  • 打赏
  • 举报
回复
cczlp(不惑)说的很对,dll和exe在同一地址空间,可以共享所有的资源,内存相互可以直接访问
MEFULEU 2007-06-28
  • 打赏
  • 举报
回复
有点象我发的某个帖子,DLL调用主程序的东西。

带窗体的DLL做过,都可以直接不用带个种类库直接在其他语言中调用。

当然接口必须很简单,比如这种传递参数
extern "C" __declspec(dllimport) void _stdcall ShellTooL(HWND hdl);

至于在DLL中创建一个东东贴到主界面,如果有大量的参数或者变量需要传递

可以考虑使用临时文件来配合,从你导出的函数来看,要做到都可以调用,

就别使用什么TFomr *pform来传递参数。

没象你这么玩过,帮你顶吧。

cczlp 2007-06-28
  • 打赏
  • 举报
回复
但是我没有顾虑到DLL的通用性和dll与宿主EXE处于不同的进程空间
============================================================
Dll和宿主Exe肯定在同一个进程空间
wanglovec 2007-06-28
  • 打赏
  • 举报
回复
顶了 没搞过
laowang2 2007-06-24
  • 打赏
  • 举报
回复
没有这样做过。
n27741 2007-06-24
  • 打赏
  • 举报
回复
我不知道楼上是怎么实现的 我将我的实验结果公布出来

1 exe和dll不带包编译 fulldebug 去掉dynamic rtl
1.1 exe调用dll 传窗体指针给dll ----不能实现
extern "C" __export void fuction1(TFomr *pform)
{
TFomr1 *pfrm = new TForm(NULL);//虽然是NULL,但是这个Form还是和DLL进程有关
pfrm->Panel1->Parent = pform; //报错 can not assign TFont to a TFont;
}
1.2 传句柄 ---不能实现
extern "C" __export void fuction1(void *frmhwnd)
{
TFomr1 *pfrm = new TForm(NULL); //虽然是NULL,但是这个Form还是和DLL进程有关
TWinControl *pwin = FindControl(frmhwnd); //返回空,因为frmhwnd属于exe进程
pfrm->Panel1->Parent = pwin;
}
1.3 传句柄 --可实现
extern "C" __export void fuction1(void *frmhwnd)
{
TFomr1 *pfrm = new TForm(NULL); //虽然是NULL,但是这个Form还是和DLL进程有关
::SetParent(pfrm->panel1->Handle , frmhwnd);
::ShowWindow(pfrm->panel1->Handle,SW_SHOW);
}

2 exe和dll都带包 fulldebug 钩use dynamic rtl
2.1 exe调用dll 传窗体指针给dll ----可实现
extern "C" __export void fuction1(TFomr *pform)
{
TFomr1 *pfrm = new TForm(NULL);//虽然是NULL,但是这个Form还是和DLL进程有关
pfrm->Panel1->Parent = pform;
}
2.2 传句柄 ---能实现
extern "C" __export void fuction1(void *frmhwnd)
{
TFomr1 *pfrm = new TForm(NULL); //虽然是NULL,但是这个Form还是和DLL进程有关
TWinControl *pwin = FindControl(frmhwnd); //返回正确的地址,
pfrm->Panel1->Parent = pwin;
}
2.3 传句柄 --可实现
extern "C" __export void fuction1(void *frmhwnd)
{
TFomr1 *pfrm = new TForm(NULL); //虽然是NULL,但是这个Form还是和DLL进程有关
::SetParent(pfrm->panel1->Handle , frmhwnd);
::ShowWindow(pfrm->panel1->Handle,SW_SHOW);
}

结论:
1 FindControl函数只能在当前进程 和 共享内存中 通过句柄返回正确的地址 其他跨进程返回NULL
2 ::SetParent 是windowsAPI 不理会进程 以及内存是否共享<特殊!>

3 对象 由当前进程创建 由当前进程销毁 但是操作可以由别的线程来完成
方法是调用windowsAPI 或者共享内存(本质也是API)

4 SetParent贴过来的对象,该对象的方法和属性保持不变<简单测试过 不能十分肯定>.

5 。。。有感觉 但是说不出来







  • 打赏
  • 举报
回复
最简单的办法是,封装成COM,封装成一个控件.就跟IE控件差不多
不要在DLL和exe之间传递对象.会死的很惨的
僵哥 2007-06-23
  • 打赏
  • 举报
回复
设计和管理这纯粹在于设计者个人,而没有模式,特别是一个利弊并存的东西。如果有绝对好用的,那么次的东西就会因为某种原因而糟到抵制。
僵哥 2007-06-23
  • 打赏
  • 举报
回复
没试过,DLL不能编译成不带包的吗?
==============================
是为共享内存,而特意采用共享机制。
n27741 2007-06-23
  • 打赏
  • 举报
回复
我再抽象一下

在dll里面new一个twincontrol控件

然后把这个控件贴在调用dll的exe的一个窗体上

最后发布的时候不带包。

如果想实现这样的功能 还有什么别的办法?

我又看了一遍pakcage的秘密,package和宿主共享内存的(李维说的)
shadowstar 2007-06-23
  • 打赏
  • 举报
回复
没试过,DLL不能编译成不带包的吗?
jacknes009 2007-06-23
  • 打赏
  • 举报
回复
看了又点糊涂,看看大家怎么说,我也想知道这方面的有关知识点,
n27741 2007-06-23
  • 打赏
  • 举报
回复
昨晚喝了点酒 话说得乱七八糟的

我来具体描述一下到底出了什么问题

1 我实现了一个功能,这个功能被公司多个产品用到,根据讨论都认为设计成DLL而不设计成类

2 之所以没有设计成静态调用,无非是因为,如果dll有改动的话,整个工程都需要重新编译

3 为了实现功能,我在dll里面new了一个窗体姑且叫它FunForm,FunForm上有一个ScrollBox

我将这个ScrollBox 的句柄传递给宿主exe,宿主EXE将把这个ScrollBox帖在自己的窗体上

面(exe 和 dll共享了对象)。

4 如此一来 必须至少带上rtl60 vcl 运行时包才能将scrollbox在exe上显示出来

5 EXE必须带XPMenu SuipackageC6 Vclx包(三方组件包) 才能在FreeLibrary的时候不出现

"访问 xxxx 模块 在rtl60.bpi xxxx地址 非法",“程序意外终止” 这样的报错

7 我在网上搜索了一下,2004年有一个贴 用英文写的
大概是说 带上运行时包 是exe和dll共享vcl组件对象的唯一解决之道

8 最终成为发布程序的时候 还必须带borlndmm.dll cc3620.dll designIDE.BPL才能run

带上这么多包,不利于程序的维护 起码显得麻烦。

所以我的疑问就是,
1 象我这样的情况,又没有办法只需要带上我开发的dll就可以使用 而不去带包。

2 有没有和宿主exe共享内存 而又可以动态调用的"dll"(资源,库)?

3 我看了庄鱼的回复 又萌发了一个想法,自己把这个funForm写成一个vcl的组件,象控件那样使用,如果自定义的vcl发生改变 整个工程还需要重新编译吗?

谢谢大家了,我知道这个问题一下很难的说完全明白。。。





  • 打赏
  • 举报
回复
封装成COM
静态链接不要依赖 BC的库.
加载更多回复(5)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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