How to specify a CodeSet for WChar string from a CORBA client
This question is related to another question with which I have been struggling: How to access CORBA interface without IDL or late-bound invoke remoting methods
I'm really stumped on how to get past this error about the CodeSet not being specified. I have been tracing into the IIOP code trying to figure out how the CodeSet can be specified, and it looks like it could be specified with a tagged component associated with the profile. Being unfamiliar with CORBA, I don't know what a tagged component is or what a profile is or how to control them, but I suspect that it may be influenced by creating a portable object interceptor, at which point I could add a tagged CodeSet component to the profile, if that means anything. I'm just going by what I can learn from the IIOP.NET code and Google.
Could someone please help me understand and hopefully control this? If the server is a black box and I need to write a client to call a method that outputs a string, how do I tell IIOP.NET what WChar CodeSet to use so it doesn't give me an error about it being unspecified. I tried OverrideDefaultCharSets from the client, but that didn't seem to have any effect. The IIOP sample code for that function shows it being used on the server开发者_JAVA技巧 side.
This was a real pain to work out, but I got it:
class MyOrbInitializer : omg.org.PortableInterceptor.ORBInitializer
{
public void post_init(omg.org.PortableInterceptor.ORBInitInfo info)
{
// Nothing to do
}
public void pre_init(omg.org.PortableInterceptor.ORBInitInfo info)
{
omg.org.IOP.Codec codec = info.codec_factory.create_codec(
new omg.org.IOP.Encoding(omg.org.IOP.ENCODING_CDR_ENCAPS.ConstVal, 1, 2));
Program.m_codec = codec;
}
}
class Program
{
public static omg.org.IOP.Codec m_codec;
static void Main(string[] args)
{
IOrbServices orb = OrbServices.GetSingleton();
orb.OverrideDefaultCharSets(CharSet.UTF8, WCharSet.UTF16);
orb.RegisterPortableInterceptorInitalizer(new MyOrbInitializer());
orb.CompleteInterceptorRegistration();
...
MarshalByRefObject objRef = context.resolve(names);
string origObjData = orb.object_to_string(objRef);
Ch.Elca.Iiop.CorbaObjRef.Ior iorObj = new Ch.Elca.Iiop.CorbaObjRef.Ior(origObjData);
CodeSetComponentData cscd = new CodeSetComponentData(
(int)Ch.Elca.Iiop.Services.CharSet.UTF8,
new int[] { (int)Ch.Elca.Iiop.Services.CharSet.UTF8 },
(int)Ch.Elca.Iiop.Services.WCharSet.UTF16,
new int[] { (int)Ch.Elca.Iiop.Services.WCharSet.UTF16 });
omg.org.IOP.TaggedComponent codesetcomp = new omg.org.IOP.TaggedComponent(
omg.org.IOP.TAG_CODE_SETS.ConstVal, m_codec.encode_value(cscd));
iorObj.Profiles[0].TaggedComponents.AddComponent(codesetcomp);
string newObjData = iorObj.ToString();
MarshalByRefObject newObj = (MarshalByRefObject)orb.string_to_object(newObjData);
ILicenseInfo li = (ILicenseInfo)newObj;
...
}
Unfortunately in my case the problem remained that the byte ordering was backwards too, so I had to go with an entirely different solution based on just getting bytes back and manually converting them to a string instead of getting string directly.
精彩评论