这个问题与我一直在努力解决的另一个问题有关:如何在没有 IDL 或后期绑定调用远程处理方法的情况下访问 CORBA 接口
我真的很困惑如何克服有关未指定代码集的错误。我一直在跟踪 IIOP 代码,试图弄清楚如何指定 CodeSet,看起来可以使用与配置文件关联的标记组件来指定它。由于不熟悉 CORBA,我不知道标记组件是什么,配置文件是什么或如何控制它们,但我怀疑它可能受到创建可移植对象拦截器的影响,此时我可以将标记的代码集组件添加到配置文件中,如果这意味着什么。我只是按照我能从 IIOP.NET 代码和谷歌学到的东西。
有人可以帮助我理解并希望控制这一点吗? 如果服务器是一个黑盒,我需要编写一个客户端来调用输出字符串的方法,我如何告诉 IIOP.NET 要使用什么 WChar CodeSet,这样它就不会给我一个关于它未指定的错误。我尝试了从客户端的OverrideDefaultCharSets,但这似乎没有任何效果。该函数的 IIOP 示例代码显示它正在服务器端使用。
这是一个真正的痛苦,但我明白了:
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;
...
}
不幸的是,就我而言,问题仍然存在,字节排序也是向后的,所以我不得不采用完全不同的解决方案,该解决方案基于仅获取字节并手动将它们转换为字符串而不是直接获取字符串。