CORBA クライアントから WChar 文字列の CodeSet を指定する方法
質問
この質問は、私が苦労している別の質問に関連しています。IDL または遅延バインド呼び出しリモーティング メソッドを使用せずに CORBA インターフェイスにアクセスする方法
CodeSet が指定されていないというこのエラーを回避する方法に本当に困っています。CodeSet をどのように指定できるかを理解しようとして IIOP コードをトレースしていましたが、プロファイルに関連付けられたタグ付きコンポーネントで指定できるようです。CORBA に詳しくないので、タグ付きコンポーネントとは何なのか、プロファイルとは何なのか、またそれらを制御する方法はわかりませんが、ポータブル オブジェクト インターセプターの作成によって影響を受けるのではないかと考えています。その時点で、タグ付きコードセットを追加できます。それが意味がある場合は、コンポーネントをプロファイルに追加します。IIOP.NET コードと Google から学べることに従うだけです。
誰かが私がこれを理解し、できれば制御するのを手伝ってくれませんか?サーバーがブラック ボックスで、文字列を出力するメソッドを呼び出すクライアントを作成する必要がある場合、指定されていないというエラーが表示されないように、どの WChar CodeSet を使用するかを IIOP.NET に伝えるにはどうすればよいでしょうか。クライアントから 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;
...
}
残念ながら、私の場合はバイト順序も逆であるという問題が残っていたため、文字列を直接取得するのではなく、バイトを取得して手動で文字列に変換するだけで、まったく異なる解決策を使用する必要がありました。