查看: 1700|回复: 4

osg插件导出问题

[复制链接]

该用户从未签到

发表于 2012-9-19 16:55:00 | 显示全部楼层 |阅读模式
请问一下各位高手们:
    我用的OSG是我自己下载的源代码,版本号为2.8.2,然后自己下载一个CMake来生成Visual Studio 2005工程,再用Visual Studio 2005编译的,工程编译成功,后来我又测试了一下生成的例子,部分能够正常运行。
    但是在osg插件的导出却令我很是想不通,我用过dumpbin 工具,使用/exports 选项查看插件的导出情况,却发现导出表为空,也就是所有的插件都没有任何的函数或者其他符号导出。
    如测试3ds读写插件:dumpbin /exports osgdb-3dsd.dll ,导出为空,对其他的所有的插件dll也是导出为空的。
    我还用过Dependency Walker工具测试过,导出表也为空。

    但是问题却出现了,我写程序调用osg加载3ds模型时,模型文件却能够成功被加载,在场景中的显示也是正确的,这是怎么回事呀。

    我学过DLL编程知识,资料显示:要能够调用一个DLL中的函数,DLL得有导出才对呀!在这种完全没有导出的情况下,这些插件中实现的函数是怎样被调用的呢?

该用户从未签到

发表于 2012-9-20 08:20:15 | 显示全部楼层
LoadLibrary,直接加载DLL,getProcAddress 获得函数地址

该用户从未签到

 楼主| 发表于 2012-9-20 09:34:12 | 显示全部楼层
问题是如果一个DLL没有导出的话,即使你用了LoadLibrary()来动态加载DLL,并且用GetProcAddress()获取函数的指针,那么GetProcAddress()函数一定会返回NULL的,你通过这种方式根本获取不到函数的指针!!我测试过的。

该用户从未签到

发表于 2012-9-20 11:33:03 | 显示全部楼层
关于文件读写插件的原理,可以看看相关的osg教程中,都有提及的

该用户从未签到

发表于 2012-9-24 08:45:22 | 显示全部楼层
本帖最后由 liuzhiyu123 于 2012-9-24 08:45 编辑
the_mercury 发表于 2012-9-20 09:34
问题是如果一个DLL没有导出的话,即使你用了LoadLibrary()来动态加载DLL,并且用GetProcAddress()获取函数的 ...


GetProcAddress()这个是没有的,是我说错了,请看下面
是这样的:
1.首先看这个函数定义,例如:
  1. REGISTER_OSGPLUGIN( osg2, ReaderWriterOSG2 )
复制代码
2.再看里面的内容
  1. #define REGISTER_OSGPLUGIN(ext, classname) \
  2.     extern "C" void osgdb_##ext(void) {} \
  3.     static osgDB::RegisterReaderWriterProxy<classname> g_proxy_##classname;
复制代码
3.再看这个
  1. static osgDB::RegisterReaderWriterProxy<classname> g_proxy_##classname
复制代码
4.在进去
  1. class RegisterReaderWriterProxy
  2. {
  3.     public:
  4.         RegisterReaderWriterProxy()
  5.         {
  6.             if (Registry::instance())
  7.             {
  8.                 _rw = new T;
  9.                 Registry::instance()->addReaderWriter(_rw.get());
  10.             }
  11.         }

  12.         ~RegisterReaderWriterProxy()
  13.         {
  14.             if (Registry::instance())
  15.             {
  16.                 Registry::instance()->removeReaderWriter(_rw.get());
  17.             }
  18.         }

  19.         T* get() { return _rw.get(); }

  20.     protected:
  21.         osg::ref_ptr<T> _rw;
  22. };
复制代码
5.最后
  1. Registry::instance()->addReaderWriter(_rw.get());
复制代码
有了这句,您就应该明白插件已经加载到那个插件链表中,然后再次进行后缀匹配,这样就找到了,当然LoadLibrary是必须的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表