⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subject_62424.htm

📁 vc
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<p>
序号:62424 发表者:陈启华 发表日期:2003-11-26 17:29:37
<br>主题:关于C++面向对象动态库调用返回std::string的问题,向高手求救,谢谢!
<br>内容:动态库程序<BR>&nbsp;&nbsp;&nbsp;&nbsp;#ifdef&nbsp;&nbsp;FILEMANAGER_EXPORTS<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#define FileManager_API __declspec(dllexport)<BR>&nbsp;&nbsp;&nbsp;&nbsp;#else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#define FileManager_API __declspec(dllimport)<BR>&nbsp;&nbsp;&nbsp;&nbsp;#endif<BR>&nbsp;&nbsp;&nbsp;&nbsp;class FileManager_API CFileManager<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline static std::string GetTemp(void){return std::string(&#34;aa&#34;);}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>主程序调用<BR>&nbsp;&nbsp;&nbsp;&nbsp;int main(int argc,char* argv[])<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string str = GetTemp();// 可以断定是此语句出的问题<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;// 在此语句中出现内存越界错误<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>这是什么原因导致,我在gnu上编译运行确没有这个问题,难道VC真的不行了,还是我有哪些地方没有注意,请高手指教,我不胜感激,谢谢!
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:dsadsdas 回复日期:2003-11-26 18:24:50
<br>内容:这个是因为你的堆有问题(你想想,你的string的内存是dll里面的分配,但是在exe里面释放)。你的选择是:自己为std::string写一个allocator,或者干脆不要用std::string。<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:陈启华 回复日期:2003-11-27 09:18:57
<br>内容:为什么dll里面的分配的内存不能在exe里面释放,它们都在一个内存地址空间内阿,<BR>你能否给我简单地讲一下原理,<BR><BR>allocator如何写,引导我一下,谢谢!
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:陈启华 回复日期:2003-11-27 13:59:47
<br>内容:该问题的根本原因我已经查出,lint386说的有点不对,<BR>动态库要求返回的类也使用__declspec(dllexport)声明,而std::string没有这个声明,<BR>所以导致了内存越界的现象.<BR><BR>目前STL都没有自动增加__declspec(dllexport)声明,所以这种在动态库中返回std类的方法就不能使用了,除非自己写stl.
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:dsadsdas 回复日期:2003-11-27 16:20:51
<br>内容:事实上,我说的是“根本原因”,你提出的只是一个“解决方法”而已。<BR>std::string是作为模版库包括进来的。如果你有一个exe,一个dll,那么他们里面各有一份std::string的实现(事实上,由于inline,可能有多份)。<BR>我们说一个简单点的例子,假如你有一个exe,并且动态的load一个dll(不是用lib,而是用LoadLibrary)那么你就会发觉,在你没有Load这个dll的时候,这个exe已经可以使用std::string相关的代码了,这就是因为exe里面也有这些代码。<BR>当你在std::string前面加了dllexport以后,意味着std::string的代码只有一份了,只在dll里面。也就是说,这个时候,没有这个dll,你的这个exe连运行都不能了(Windows会报错)。当然,因为std::string的代码只有在dll里面有一份了,那么分配/释放内存当然没问题了。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:陈启华 回复日期:2003-11-28 09:27:47
<br>内容:谢谢!我现在明白这个道理了,但因为这些原因,我就无法使动态库接口函数返回std::string吗,你有方法吗?盼回复,因为若要修改接口程序涉及的东西太多了
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
<font color=red>答案被接受</font><br>回复者:dsadsdas 回复日期:2003-11-28 10:40:36
<br>内容:我说了,改一个allocator。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:dsadsdas 回复日期:2003-11-28 10:41:49
<br>内容:还有,如果你使用的类库不杂的话,重载全局new也是一个办法。不过如果你使用了类似于MFC之类的东西,恐怕会有些问题。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:陈启华 回复日期:2003-11-28 10:49:14
<br>内容:修改allocator:<BR>std::basic_string&lt;char,char_traits&lt;char&gt;,myalloc&gt;<BR>为什么重写myalloc就可以解决问题,能否简单告知我原理,如果太复杂,那告诉我如何参考相关资料,谢谢!<BR><BR>感谢你回答了我这么多问题,我接受你的回复,但我迫切盼望你能够帮我解决彻底这个问题,谢谢.
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:dsadsdas 回复日期:2003-11-28 16:12:53
<br>内容:你在你的dll里面导出两个函数,一个用于分配内存,一个用于释放内存。<BR>allocator里面有两个函数,一个用于分配内存,一个用于释放内存。<BR>你可以改写它们,让他们调用你在dll里面导出的那两个。<BR>这样,就完全安全了。<BR><BR>重载全局的new/delete一样。总之,让分配和释放在一个模块内就可以了。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:陈启华 回复日期:2003-11-28 16:30:50
<br>内容:谢谢!我会尝试一下你的方法,但是为什么呢?<BR><BR>另外:<BR>我发现将vc/project/setting/c++/codeGeneration/useRuntimeLibrary统统设置为MultithreadDll<BR>该问题并得到了解决,你知道是什么原因吗?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -