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");
我花了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");
相关文章推荐
- 错误记录(五)Error creating bean with name 'sessionFactory' defined in file
- Error: No room left in memory section, Image is too large for defined regions
- Linker Error: _funcName defined in module XXX.c is duplicated in module XXX.c
- 安装rvds2.2,出现Error: %variable HOSTPLAT is not defined in File RDI\armsd\1.3.1\66\install.xml
- Linker Error: _funcName defined in module XXX.c is duplicated in module XXX.c
- PHP error:ERROR: No pool defined. at least one pool section must be specified in config file
- jmeter3.2生成图形html遇到的问题Error in NonGUIDriver java.lang.IllegalArgumentException: Results file:log is not empty
- ERROR: No pool defined. at least one pool section must be specified in config file
- Python使用eval强制转换字符串为字典时报错:File "<string>", line 1, in <module> NameError: name 'nan' is not defined
- 启动AVD时候失败PANIC: ANDROID_SDK_HOME is defined but could not find Test.ini file in $ANDROID_SDK_HOME\.a
- c++链接错误:error LNK2005:*** already defined in ***
- “error LNK2005:…… already defined in”错误解决办法
- JAVA错误:The public type *** must be defined in its own file***
- GIT error: object file is empty?
- GAE报错“NameError: global name 'execfile' is not defined”
- 在 12cR1 数据库中创建测试用户是报 ORA-65096 错误(2c: ORA-65049: creation of local user or role is not allowed in C)
- Uncaught ReferenceError: $ is not defined 错误的解决办法
- bug之java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class
- It is an error to use a section registered allowDefinition='MachineToApplication' beyond application level. 错误
- modelsim10.4仿真错误Error: (vlog-7) Failed to open design unit file "XXXXX" in read mode解决办法