0

两个 IDL 文件,testbase.idl

module Test{
   enum JobType{
       TYPE1,
        TYPE2,
       TYPE3
   };

   struct UserContext{
       string name;
       string ssoToken;
   };
};

testhello.idl:

#include "testbase.idl"
module Test 
{
   interface Hello
   {
    void createJob(in UserContext type);
   };
};

和 Hello.mpc 内容是:

project(testbaseIDL): taoidldefaults, anytypecode {
      idlflags += -Wb,stub_export_macro=TEST_BASE_STUB_Export -Wb,stub_export_include=test_base_stub_export.h -Wb,skel_export_macro=TEST_BASE_SKEL_Export -Wb,skel_export_include=test_base_skel_export.h
      IDL_Files {
          testhello.idl
      }
  custom_only = 1
}

project(testhelloIDL): taoidldefaults, anytypecode {
     idlflags   += -Wb,stub_export_macro=TEST_HELLO_STUB_Export -Wb,stub_export_include=test_hello_stub_export.h -Wb,skel_export_macro=TEST_HELLO_SKEL_Export -Wb,skel_export_include=test_hello_skel_export.h
      IDL_Files {
          testhello.idl
      }
  custom_only = 1
}

project(test_base_server): naming, iortable, utils, avoids_corba_e_micro, anytypecode {
    sharedname = test_base_server
    after += *IDL
    Source_Files {
          testbaseS.cpp
    }
   Header_Files{
   testbaseS.h
        testbaseC.h
test_base_skel_export.h 
    }

  dynamicflags += TEST_BASE_SKEL_BUILD_DLL TEST_BASE_STUB_BUILD_DLL
  }

project(test_base_client): naming, iortable, utils,anytypecode {
   sharedname = test_base_client
   dynamicflags += TEST_BASE_STUB_BUILD_DLL
   Source_Files {
        testbaseC.cpp
   }
   Header_Files{
       test_base_stub_export.h 
   testbaseC.h
   }
 }

 project(testhelloserver): naming, iortable, utils, avoids_corba_e_micro,anytypecode {
     sharedname = test_hello_server
     dynamicflags += TEST_HELLO_SKEL_BUILD_DLL
     libs += test_base_server test_hello_client test_base_client
     Source_Files {
           testhelloS.cpp
     }
    Header_Files{
     testhelloS.h
         testbaseS.h
        test_hello_skel_export.h
   }

  }

 project(testhelloclient): naming, iortable, utils,anytypecode {
         sharedname = test_hello_client
         dynamicflags += TEST_HELLO_STUB_BUILD_DLL
         libs += test_base_client
        Source_Files {
              testhelloC.cpp
        }
      Header_Files{
         testhelloC.h
        testbaseC.h
        test_hello_stub_export.h
      }
  }

我想做一些演示。mpc 将生成 4 个主要项目(testbaseClient、testbaseserver、testhelloServer 和 testhelloClient),每个项目将生成一个 dll 和库,所有这些都用作每个 IDL 的骨架和存根。

在VS2008中,在构建testUDL、testbaseclient、testbaseServer之后,testbaseserver和testbaseclient的链接都失败了,因为链接找不到一些符号。错误消息是:

1>testhelloC.obj : 错误 LNK2019: 无法解析的外部符号 "bool __cdecl operator::marshal(class TAO_OutputCDR &)" (?marshal@?$In_Var_Size_Argument_T@UUserContext@Test@@VAny_Insert_Policy_Stream@TAO@@@TAO@@UAE_NAAVTAO_OutputCDR@@ @Z)
1>testhelloC.obj:错误 LNK2019:无法解析的外部符号“void __cdecl operator::any_insert(class CORBA::Any *,struct Test::UserContext const &)”(?any_insert@?$Any_Insert_Policy_Stream@UUserContext@Test@@@ TAO@@SAXPAVany@CORBA@@ABUUserContext@Test@@@Z)
1>testhelloS.obj : 错误 LNK2001: 无法解析的外部符号 "void __cdecl operatortesthelloS.obj : 错误 LNK2019: 无法解析的外部符号 "bool __cdecl operator>>(class TAO_InputCDR &,struct Test::UserContext &)" (??5@YA_NAAVTAO_InputCDR @@AAUUserContext@Test@@@Z) 在函数“public: virtual bool __thiscall TAO::In_Var_Size_SArgument_T::demarshal(class TAO_InputCDR &)”(?demarshal@?$In_Var_Size_SArgument_T@UUserContext@Test@@VAny_Insert_Policy_Stream@TAO@@ @TAO@@UAE_NAAVTAO_InputCDR@@@Z)
1>.\test_hello_serverd.dll : 致命错误 LNK1120: 3 unresolved externals

我理解错误:仅当链接无法从自身或依赖库中找到这些符号时,才会发生未解析的外部符号。因此,我为 testhelloclient 和 testhelloserver 添加了 libs += test_base_server test_base_client。重新生成所有项目后,结果是一样的。“未解决的外部符号”仍然存在。

我怀疑这两个生成的基础库是错误的,我使用命令:dumpbin /EXPORTS 导出所有符号,并且没有报告未解析的外部符号。

Microsoft (R) COFF/PE Dumper 版本 9.00.30729.01
版权所有 (C) 微软公司。版权所有。


文件 test_base_clientd.dll 的转储

文件类型:DLL

  部分包含 test_base_clientd.dll 的以下导出

    00000000 个特征
    526C30F9 时间日期戳 Sat Oct 26 18:15:37 2013
        0.00 版本
           1 个序数基数
           1个功能
           1个名字

    序号提示 RVA 名称

          1 0 00003130 ??4_Init_locks@std@@QAEAAV01@ABV01@@Z = ??4_Init_locks@std@@QAEAAV01@ABV01@@Z (公共:类 std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks 常量 &))

  概括

        1000 个数据
        2000 .idata
        3000 .rdata
        1000 .重新定位
        1000 .rsrc
        9000.文本
Microsoft (R) COFF/PE Dumper 版本 9.00.30729.01
版权所有 (C) 微软公司。版权所有。


文件 test_base_serverd.dll 的转储

文件类型:DLL

  部分包含 test_base_serverd.dll 的以下导出

    00000000 个特征
    526C2AEE 时间日期戳 Sat Oct 26 17:49:50 2013
        0.00 版本
           1 个序数基数
           1个功能
           1个名字

    序号提示 RVA 名称

          1 0 00003130 ??4_Init_locks@std@@QAEAAV01@ABV01@@Z = ??4_Init_locks@std@@QAEAAV01@ABV01@@Z (公共:类 std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks 常量 &))

  概括

        1000 个数据
        2000 .idata
        3000 .rdata
        1000 .重新定位
        1000 .rsrc
        9000.文本
Microsoft (R) COFF/PE Dumper 版本 9.00.30729.01
版权所有 (C) 微软公司。版权所有。


文件 test_base_serverd.lib 的转储

文件类型:图书馆

     出口

       序号

                  ??4_Init_locks@std@@QAEAAV01@ABV01@@Z(公共:类 std::_Init_locks & __thiscall std::_Init_locks::operator=(类 std::_Init_locks const &))

  概括

          E1 .debug$S
          14 .idata$2
          14 .idata$3
           4 .idata$4
           4 .idata$5
          16 .idata$6
Microsoft (R) COFF/PE Dumper 版本 9.00.30729.01
版权所有 (C) 微软公司。版权所有。


文件 test_base_clientd.lib 的转储

文件类型:图书馆

     出口

       序号

                  ??4_Init_locks@std@@QAEAAV01@ABV01@@Z(公共:类 std::_Init_locks & __thiscall std::_Init_locks::operator=(类 std::_Init_locks const &))

  概括

          E1 .debug$S
          14 .idata$2
          14 .idata$3
           4 .idata$4
           4 .idata$5
          16 .idata$6

然后我感到困惑的是:1)链接需要在制作库项目期间所有可用的符号。我过去在 unix 上的经验是,只有在制作可执行文件时才需要所有符号。

2)如何在这里解决这个问题?我应该为 testIDL 项目添加一些参数吗?

[更新]:

为 testhelloclient 添加了所有 *C.cpp 并且所有 *C.cpp 和 *S.cpp 都会使编译工作。

然而,这并不像我预期的那样。我想将每个 IDL 编译成两个库:一个用于存根,另一个用于骨架。那么以后我只需要为其他项目提供带有相应头文件的stub/skeleton即可。当 .lib/.dll 和头文件可用时,骨架/子应用程序无需编译任何由 IDL 生成的 cpp 文件。

目前,上面生成的 *.lib 文件中没有一个包含来自 *C.cpp 或 *S.cpp 的符号(dumpbin 结果与之前的帖子相似,只有 1 个函数)。其他应用程序仍会报告未解析的符号,因为 .lib 不包含任何导出符号。

今天下午我阅读了 MSDN: http: //msdn.microsoft.com/en-us/library/ms235636%28v=vs.90%29.aspx 。对于dll的导出符号,函数声明为:

static __declspec(dllexport) double Add(double a, double b);

但是idl生成的c头文件似乎不遵循这种方式..

VC 似乎与 Linux 中的 GCC 大不相同。有什么解决办法吗?我不可能在IDL生成的头文件中为每个函数添加_declsepc?问题简化为:VC 中从 IDL 生成的库中没有导出任何符号(我重命名了标题以获得更多说明)

[更多更新] 我回到 tao_idl 命令,似乎是由以下选项引起的: -Wb,skeleton_export_include="headerfile.h" export_macro..

似乎所有这些文件和宏都生成了....有没有更好的生成 .mpc 文件,这些 headerfile.h 和宏是什么?

[更新] 它现在适用于更新的 mpc 文件(见上文)。导出文件由 $ACE_ROOT/bin 目录中的 generate_export_file.pl 生成。命令如下:

generate_export_file.pl TEST_HELLO_STUB > test_hello_stub_export.h

谢谢大家。

4

1 回答 1

0

您还必须在 IDL 文件的其他项目中添加 anytypecode 作为基础项目,而不仅仅是 IDL 文件本身。也只是使用命名而不是命名exe,您只需要使用命名服务存根,而不是完整的服务实现

于 2013-10-27T15:36:24.197 回答