两个 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
谢谢大家。