Two IDL files, 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);
};
};
and Hello.mpc content is:
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
}
}
I want to do some demo. The mpc would generate 4 main projects(testbaseClient, testbaseserver, testhelloServer and testhelloClient) and each projects would generate one dll and library and all of them are used as skeleton and stub for each IDL.
In VS2008, after building testUDL, testbaseclient, testbaseServer, the links for both testbaseserver and testbaseclient fail because link can not find some symbols. The error messages are:
1>testhelloC.obj : error LNK2019: unresolved external symbol "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 : error LNK2019: unresolved external symbol "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 : error LNK2001: unresolved external symbol "void __cdecl operatortesthelloS.obj : error LNK2019: unresolved external symbol "bool __cdecl operator>>(class TAO_InputCDR &,struct Test::UserContext &)" (??5@YA_NAAVTAO_InputCDR@@AAUUserContext@Test@@@Z) referenced in function "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 : fatal error LNK1120: 3 unresolved externals
I understand the error: unresolved external symbol happens only if link could not find those symbol from itself or dependent libraries. Therefore, I added libs += test_base_server test_base_client for both testhelloclient and testhelloserver. After regenerating all project, the result is the same. The "unresolved external symbol" still there.
I suspect the two generated base library are wrong and I use command: dumpbin /EXPORTS to export all symbol and none reported unresolved external symbol are there.
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file test_base_clientd.dll File Type: DLL Section contains the following exports for test_base_clientd.dll 00000000 characteristics 526C30F9 time date stamp Sat Oct 26 18:15:37 2013 0.00 version 1 ordinal base 1 number of functions 1 number of names ordinal hint RVA name 1 0 00003130 ??4_Init_locks@std@@QAEAAV01@ABV01@@Z = ??4_Init_locks@std@@QAEAAV01@ABV01@@Z (public: class std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks const &)) Summary 1000 .data 2000 .idata 3000 .rdata 1000 .reloc 1000 .rsrc 9000 .text Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file test_base_serverd.dll File Type: DLL Section contains the following exports for test_base_serverd.dll 00000000 characteristics 526C2AEE time date stamp Sat Oct 26 17:49:50 2013 0.00 version 1 ordinal base 1 number of functions 1 number of names ordinal hint RVA name 1 0 00003130 ??4_Init_locks@std@@QAEAAV01@ABV01@@Z = ??4_Init_locks@std@@QAEAAV01@ABV01@@Z (public: class std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks const &)) Summary 1000 .data 2000 .idata 3000 .rdata 1000 .reloc 1000 .rsrc 9000 .text Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file test_base_serverd.lib File Type: LIBRARY Exports ordinal name ??4_Init_locks@std@@QAEAAV01@ABV01@@Z (public: class std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks const &)) Summary E1 .debug$S 14 .idata$2 14 .idata$3 4 .idata$4 4 .idata$5 16 .idata$6 Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file test_base_clientd.lib File Type: LIBRARY Exports ordinal name ??4_Init_locks@std@@QAEAAV01@ABV01@@Z (public: class std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks const &)) Summary E1 .debug$S 14 .idata$2 14 .idata$3 4 .idata$4 4 .idata$5 16 .idata$6
Then what I am confused is that: 1) Would link requires all symbol available during making library project. What my past experience in unix is that all symbol is required only if it is on making executable file.
2) How to resolve this issue here? Should I add some arguments for testIDL projects?
[UPdate]:
Added all *C.cpp for testhelloclient and all *C.cpp and *S.cpp would make compilation work.
However, this is not as I expected. I want to compile each IDL into two libraries: one is for stub and another is for skeleton. Then in the future, I only need to deliver stub/skeleton with corresponding header files for other projects. It is unnecessary for skeleton/sub application to compile any of cpp files generated by IDL when .lib/.dll and header file is available.
Currently, none of *.lib files generated above contain symbol from *C.cpp or *S.cpp(the dumpbin result is similar as post previous, only 1 function). And other application would still report unresolve symbols because .lib does not contain any export symbols.
I read MSDN: http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.90%29.aspx this afternoon. For export symbol of dll, the function is declared as:
static __declspec(dllexport) double Add(double a, double b);
but idl generated c header files seems not follow this way..
VC seems much different with GCC in Linux. Is there some solution?It is impossible for I to add _declsepc for each functions in IDL generated header files? The issue is simplified as: none of symbols is export in library generated from IDL in VC(I renamed title for more clarification)
[More update] I go back to the tao_idl command, it seems it is caused by options like: -Wb,skeleton_export_include="headerfile.h" export_macro..
It seems all these files and macros are generated....Is there any better to gernated .mpc file and are these headerfile.h and macros?
[UPDATE] It now works with updated mpc file(see above). The export files are generated by generate_export_file.pl which is in $ACE_ROOT/bin directory. The command is like:
generate_export_file.pl TEST_HELLO_STUB > test_hello_stub_export.h
Thanks all.
You have to add anytypecode also as base project in the other projects in the IDL file, not only with the IDL file itself. Also just use naming instead of namingexe, you only need to use the naming service stubs, not the full service implementation