您的位置:首页 > 编程语言 > C语言/C++

C++Builder 6 [BCB6] 共享数据段 错误 测试 (bug 、[Linker Error] Section SHSEG defined in .def file is empty)

2009-12-04 14:13 627 查看
   这个话题,可以说网上绝对没有一个帖子或者答案是齐全的,是让人信服的。更有些都是摘抄的BCB4的一些论坛上的

   我花了4个小时,对BCB的共享数据段做了一些较浅,易懂的测试。网上的一些帖子LZ说自己解决了,然后还给了很多自己的看法,大多数都是有问题,或者是断章取义的。

   比如以下是一个作者给出的编译成功的条件:

   1)ShareUnit.cpp文件中必须用struct,(2)并且必须申明一个该struct的全局变量,(3)并且一定要对这样的struct进行初始化。(4)输出DLL的函数必须至少使用一次上述的struct.

  原贴地址:

 http://topic.csdn.net/t/20031022/10/2381756.html

   是个程序员都知道,怎么可能这样呢,确实,这个LZ太冲动了,太急着下定义了,没有仔细的去考虑通解。(这里没有任何的人身攻击的意思)

  事实是他搞错了,经我测试,他是C++的语法搞错了,我们知道,在C++出来之前,C语言是几乎用不到.h文件的。.h文件最广泛的用处是给“类”定义提供了存放处。BCB中如果创建一个单元Unit,那么会同时创建2个文件:.cpp和.h。这位楼主肯定是用了这个方法创建了一个unit,如果.h里面不放任何东西或者放个类都是正确的,我们又知道,我们所要共享的变量是要放在.cpp文件中的,我们在主cpp中要用extern来访问这些变量。这位楼主导致错误的原因是:

(1)他新建了一个unit

(2)他在主cpp中用头文件加载的形式访问了共享cpp中的数据:#include<共享.cpp>  【.h文件对主cpp无用】

(3)这样会导致编译时警告,某个数据在两个模块中都被定义了。(加了共享数据定义后就会便一步成功,继续往下看)

(4)后来他去掉了#include<共享.cpp> 换用了extern可问题又发生了

(5)他发现.h的头文件里的结构体struct对主cpp是毫无意义的,所以会发生定义没有被用到的警告。

(6)最后他在主文件(输出dll)中也用了struct,在共享.cpp中也用了,这才使整个工程成功的编译了。

 

其实,讲到这,大家可能有个疑问,上面第3步和第5步,虽然编译有警告,但也可以运行正确。那位什么事实没有运行成功呢。这就要讲到BCB中对含有共享数据工程编译时的异常处理,经过我的测试,我发现,除了很明显的语法小错误等(本cpp中一些数据的定义,和函数的用法)会被作为一般异常处理之外,其他的小错误、警告等都会被作为共享数据工程编译错误来处理,这可能是BCB编译器的一个bug,从另一方面来说,也是对我们程序员的基本功的考验,总之如果有整个工程编译不成功,肯定有错误,但不一定是共享数据段出问题了。可能是其他的部分的错误导致的,而这些错误都被当成是共享数据的异常处理了,所以,很多人在下了网上的大师级的例子后,认为编译还是有错误:

错误代码最多的是:

[Linker Error] Section SHSEG defined in .def file is empty

如果你觉得上面的解释有点绕口,那我总结一下:

 

要想编译通过,要注意一点,
     除去共享数据文件(ShareData.dll和Data.def)之后,要使单独的DLL文件能编译成功,而且一点错误也不能有,包括warning也不行,否则,均会被共享数据定义异常所捕获,错误代码为:
[Linker Error] Section SHSEG defined in .def file is empty
给我造们造成共享数据段发生错误的假象。

所以如果你排除了公共数据段的错误之后,基本觉得公共数据段和大师给的例子没有区别的时候,如果还是编译不通过,那么我们该找找自己写的模块是否有错误,而不要怀疑大师是不是粗心了。

   一般的共享数据的定义如下:

首先:

 ShareData.cpp//不需要.h文件,在new 中直接创建cpp文件

#pragma option -zRSHSEG

#pragma option -zTSHCLASS

//下面是要全局共享的数据如
int count=1;

然后:

为这个ShareData.cpp文件写一个link时文件.def,这个def文件的名称要和主dll一样,设dll为:name.dll

那么这个def名为:name.def  内容为:

SEGMENTS  SHSEG  CLASS   'SHARECLS'   SHARED

 

最后再main.cpp中调用时:

 要加上:

 extern int a;

 一般这样就OK了,但是最好再加上

USEUNIT("ShareData.cpp");

USEDEF("name.def");

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐