none
C# 同士のDLL呼び出し。.NET 2.0 -> 1.1 RRS feed

  • 質問

  • 初めて利用させていただきます。

    Windows XP 用プログラムの開発で、VS 2005を使っています。

    C#の、.NET 1.1で作成済みの DLLがあります。 自社のDLLではないので変更できません。

    これを、.NET 2.0 のC#から呼び出して使っていました。

    ところが、 MS07-040 のupdate を適用後、この呼び出しが上手く行かなくなりました。

    呼び出しそのものはできているようなのですが、値が返ってこないという症状です。

    エラーになるわけでもないのでプログラムから対応できません。

    MS07-040 を uninstall して、.NET Framework 2.0を入れなおすと正常動作します。

    なので、プログラムのアルゴリズムや文法上の問題ではなさそうです。

       

    セキュリティパッチによる影響なので、2.0 -> 1.1 のCLRをまたいだ呼び出しが

    セキュリティホールと見做されているのかなあと思いますが、対策が判りません。

    呼び出し側のDLLを何かに登録するとか、DLLの呼び出し方を変えるとか、

    #要するにどうすればよいのか・・

    教えていただけないでしょうか。

     

    蛇足ながら、DLL呼び出しを unsafe { } してみましたが駄目でした。

     

    宜しくお願いいたします。

     

    2008年1月4日 5:32

すべての返信

  • あなたが作成している呼び出し側のプログラムをVS2003.netで、作成してください。

     You See さんからの引用

    C#の、.NET 1.1で作成済みの DLLがあります。 自社のDLLではないので変更できません。

    これを、.NET 2.0 のC#から呼び出して使っていました。

    この場合、.NET 1.1で作成済みの DLLも、.Net Framework 2.0上で動作しますが、

    確か、完全な動作保障はされてなかったと思います。

    2008年1月4日 6:46
  •  

    返信をありがとうございます。

    当然のごとく、VS 2003でコンパイルしなおしという案はあったのですが、

    同じモジュール(バイナリ)をVistaでも使っていること、と

    もともと VS 2003で開発したものを、機能強化するために VS 2005に移行したもの、

    といった事情があって、いまさら戻れないのです。 

    (ソースレベルで変更するだけでなく機能削除まで必要になってしまうため)

     

    2008年1月4日 8:32
  • いや、あなた方の事情を説明してもらっても、この場合、何ら状況は変わりませんよね?

    っていうか、開発に入る前に、その辺のシステム要件について、そもそも、何の確認も取っていないのでしょうか?

    2008年1月4日 9:18
  • どんな型を返すメソッドなのか、そのメソッドがどんな役割を行っているのか、そのメソッドはどの程度動作しているのか、全く分かりません。

    使用しているクラスライブラリの潜在的な不具合の可能性もありますし、一般的な問題とは現状で言い切れません。

    もう少し、原因や再現条件を切り分けてみてはいかがでしょうか?

    そうしてもなお、解決ができそうにない場合は再現できそうな情報や怪しい動き等、分かったことを書き添えてみてください。

     

    疑問例

    .NET 2.0 SP1の有無は?

    簡単な.NET 1.1ベースのクラスライブラリと.NET 2.0アプリでも再現しますか?

    対象のクラスライブラリの他のクラス、メソッドも同様ですか?

    どんな形で呼び出していますか?

     

    参考

    .NET 1.1で即席で作ったクラスでint型を返すメソッドを実装しました。

    これを、.NET 2.0 SP1環境下(VC#2005Exp)で呼び出したところ、問題なく値が得られました。

    #もちろん、値型という簡単なものであるため、比較できないものだと思います。

     

    動作試験イメージ(実際には別のコードで試していますが、やっていることは次のコードと余り変わりません。)

    コード ブロック

    Net11TestClass instance = new Net11TestClass();

    int value = instance.Add(11, 20);

    Console.WriteLine(value.ToString());

     

     

     

    2008年1月4日 9:30
    モデレータ
  •  

    お返事&サンプルまでいただき、ありがとうございます。

     

    問題のプログラムは、1年近く動作実績のあるものです。

    .NET Framework 2.0 -> 1.1 の呼び出し自体は問題ないし、呼び出したDLLも

    セキュリティパッチを適用しなければ動いています。

    .NET Framework 2.0 SP1を適用したとたんに、問題が出てしまいます。

     

    また、DLLの呼び出し部分は、呼び出し側から見ると、string[] を返すだけのものです。

    呼び出し側は極力簡単にした、ほぼ呼び出すだけのプログラムでも問題がおきる

    ことを確認済みです。  

    #ですから、コーディングレベルのプログラムの問題ではないだろうと思っているのですが・・  

      

    {

      dll.initialize();

      ans = dll.getstrings();

    }  // <= ほぼこれだけの処理ですが、SP1を適用すると期待する値が得られず、ans =null

       // になってしまいました。

       

    #この string[]を求めるために、DLL内部ではいろいろやっています。

     が、その部分は自社のものでないため委細不明です。

      

     

    2008年1月4日 10:24
  •  

     You See さんからの引用

    {

      dll.initialize();

      ans = dll.getstrings();

    }  // <= ほぼこれだけの処理ですが、SP1を適用すると期待する値が得られず、ans =null

       // になってしまいました。

     

    次のようなコードでは問題が再現できません。

    (実行環境はXPSP2で.NET Framework 3.5導入済み。.NET 2.0SP1は自動的に適用)

     

    .NET 1.1側のコード(VC#2003 Pro)

    コード ブロック

     public class Class1
     {
      public Class1()
      {
      }

      private string[] _Array;
      public void Initialize()
      {
       _Array = new string[]{
        "abcdef",
        "ghijkl",
        "mnopqr",
        "stuvwx",
        "yz",
       };
      }

      public string[] GetStrings()
      {
       return _Array;
      }
     }

     

     

    .NET 2.0側のコード(VC#2005Exp)

    コード ブロック

        class Program
        {
            static void Main(string[] args)
            {
                Class1 instance = new Class1();
                instance.Initialize();
                string[] strArray = instance.GetStrings();
                foreach (string item in strArray)
                {
                    Console.WriteLine(item);
                }
            }
        }

     

     

     You See さんからの引用

    また、DLLの呼び出し部分は、呼び出し側から見ると、string[] を返すだけのものです。

    呼び出し側は極力簡単にした、ほぼ呼び出すだけのプログラムでも問題がおきる

    ことを確認済みです。  

    #ですから、コーディングレベルのプログラムの問題ではないだろうと思っているのですが・・  

     

    #この string[]を求めるために、DLL内部ではいろいろやっています。

     が、その部分は自社のものでないため委細不明です。

     

    そのブラックボックスの中で、バージョンに依存する処理があったりするのではないでしょうか?

    (***でなければreturn null;するとか、ドキュメントではNGとされているが、たまたま通ったコードを使用しているとか)

    バージョンに依存するというのは考えにくいのですが、ブラックボックスである以上、変なコードがないとは言い切れません。

    何にせよ、そのDLLの開発元に問い合わせてみてはいかがですか?

     

    現状では一般的に起こる問題に見えないため、「何とかなりませんか?」と聞かれても答えられない気がします。

     

    2008年1月4日 10:58
    モデレータ
  • 試しに、.NET 1.1アプリで呼び出すとどうなりますか?

    .NET 1.1のセキュリティパッチの有無で動作が変わりますか?

    (参考:http://www.microsoft.com/japan/technet/security/bulletin/MS07-040.mspx

     

    もし、これで意図した通りに動作しないようなら、確実にDLLに問題があると思います。

    2008年1月4日 11:06
    モデレータ
  •  Microsoft .NET Framework 1.1 Hotfix (KB928366) または NDP.1sp1-KB928366-X86.exe ですね。

    .NET 1.1からの呼び出しは問題ありません。上記の update 実施しても大丈夫です。

    MS07-40 を実施前後に、.NET 1.1でコンパイルした同じサンプルコードで確認しました。

    ですので、 .NET 2.0 からの呼び出し時、それもセキュリティパッチ実施にともなう非互換だと考えています。

       

    DLL内部の処理は、いろいろやっていることは確かなのですが、手は付けられません。

    自社開発でないとか契約上の問題とかだけでなく、簡単に変更できるような単純な処理でないのです。(;_Wink

     

    >バージョンに依存する処理

     

     これはありえないです。 .NET 2.0 からの呼び出しはもんだいありません。

     MS07-40 、もっというと .NET Framework 2.0 SP1 を適用したときに問題がおきます。

     

     テストしていただいて大変ありがたいのですが、コーディングレベルの問題ではないと思っています。

      .NET Framework 2.0 のセキュリティパッチに伴う(この場合)過剰なチェックを

     迂回する技か、なにかの設定があるのだと思っています。

    2008年1月7日 1:26
  • ps.

      泣き顔の顔文字を書いたつもりが、ウィンクしている画になりました。 

     困っています。笑ってなんかいません。 ・・・

     

     

    2008年1月7日 1:29
  • もし可能なら、他社製のそのDLLを .NET Framework2.0 をターゲットとして再ビルドしてもらうだけで状況の改善になるかもしれません。

    それが無理なら、.NET Remoting なんかを使い、要するに別プロセスで動かすしか道はないんじゃないでしょうか。当然パフォーマンスの劣化や余計な作業は避けられません。

     

    2008年1月7日 3:57
  • アドバイスをありがとうございます。

     

    >他社製のそのDLLを .NET Framework2.0 をターゲットとして再ビルドしてもらうだけで

      

     これ自体難しい(できない)のですが、かりにできたとしても上手く行くかどうかは

    良いとこ、五分五分じゃないかと思っています。

    というのは、 .NET Framework 2.0 では問題なくうごいていて、SP1を適用した時点での問題なので、

    非互換があるのは、プログラム(のオブジェクト)ではなくて、SP1 ないし MS07-40と思えるからです。

    .NET Framework 2.0 SP1 をターゲットにして再ビルドするのならわかりますが、

    .NET Framework 2.0 をターゲットにしても、非互換は残ってしまいそうだから。

    2008年1月7日 4:51
  •  You See さんからの引用

      .NET Framework 2.0 のセキュリティパッチに伴う(この場合)過剰なチェックを

     迂回する技か、なにかの設定があるのだと思っています。

    そう思うのなら、こんなところで時間を潰していないで、MSに聞いてください。

     

    それとも、裏技か何か非公式な方法を探しておられるのでしょうか?

    たとえそんなものが見つかったとしても、将来のアップデート/パッチで、また動かなくなるかもしれませんよね?

    そんなものを、商品として出荷しようとされておられるのでしょうか?

     

     You See さんからの引用

    もともと VS 2003で開発したものを、機能強化するために VS 2005に移行したもの、

    これの意味が全くわかりません。VS2005に移行した「だけ」では、機能強化なんてされませんよね?

     

    もしかして、.Net Framework 2.0でしかサポートされていない、他の他社製DLLを使って、機能強化しようとしているのでしょうか?

    であれば、囚人さんのおっしゃる方法を調べてみては?

     

    ではなくて、.Net Framework 2.0で追加されたクラス/メソッドを使おうとしているのでしょうか?

    であれば、(VS2003に戻って)それらを自作されてはどうでしょうか?

    # 大概のものは、ネットを漁れば、参考になるコードが落ちてるはず。

    大変な手間だとは思いますが、このままでは、プロジェクトそのものが潰れてしまうのですよね?

     

    P.S.

    スレ主さんは、「近道に見えるが、実際は行き止まり。」の道を進んでおられるように見受けられます。

    2008年1月7日 7:40
  • あー失敬。勿論


    .NET Framework 2.0 SP1 をターゲットにして再ビルドするのならわかりますが

    でいいですよ。そういう指定はできないですが。「開発環境に SP1 があたった状態でビルド」という事で。


    今の状況は .NET Framework 2.0 (あるいはSP1) で .NET Framework 1.1 用のアセンブリを動かす、要するに CLR 2.0 で 1.1 用のアセンブリを実行するという「推奨されていない状況(多分)」で実行されているわけですよね。この状態では、SP1 に問題があるかどうかは分かりません。


    仮に .NET Framework 2.0 で再ビルドし、.NET Framework 2.0 環境で動く事が確認できれば .NET Framework 2.0 SP1 で動く事は期待してよいのではないでしょうか? 2.0 で動いていたものが SP1 になって動かなくなるようではランタイムが駄目という事で、「SP1 のバグですよ」とまぁ判断つきますよね? まず、何が問題を一つ一つ片付けてはどうでしょうか?


    サイドバイサイドはプロセス単位でしかできません。一方が 2.0 一方が 1.1 で動かすという事ができないので、両方のバージョンをあわせるか、先に挙げたようにプロセスを分けるしかないですよ。

     

    2008年1月7日 7:59
  •  

    > こんなところで時間を潰していないで、

     ありがとうございます。

     もちろん、いろいろ手を尽くそうとしておりまして、ここに投稿させていただいたのもその一つです。

     

     同じ問題を経験した方が一人くらいいるのではないかと思いまして。

     

    > 裏技か何か非公式な方法を探しておられるのでしょうか?

     例えば、LAN関係のプログラムで、ファイアウォールの例外に登録する必要があるとかの、

     そんな類の設定があるなかなと思っています。

     

    > これの意味が全くわかりません。

      機能強化のために改良した際、1.1 では難しいと思える部分があり、 2.0を使いました。

     このプログラムは既に出荷済みで、すでに一年近く、安定して動いている(た)ものです。

     マイナーなアップデートのために開発は続けているのですが、いまさら全部を 1.1 

     (vs2003) に戻すわけにもいきません。  ・・(泣)

      

    2008年1月7日 11:28
  •  You See さんからの引用

    > これの意味が全くわかりません。

      機能強化のために改良した際、1.1 では難しいと思える部分があり、 2.0を使いました。

     このプログラムは既に出荷済みで、すでに一年近く、安定して動いている(た)ものです。

     マイナーなアップデートのために開発は続けているのですが、いまさら全部を 1.1 

     (vs2003) に戻すわけにもいきません。  ・・(泣)

    そうですか。

    では、実際問題としては、囚人さんの最初のカキコどおりに動くしか、道はないと思います。

    # そのDLLの開発元は、何で、.Net Framework 2.0への対応を拒否しているのでしょうかね?

    # それが判れば、いくらか動きようがあるように思えますが。。

     

    正直、

     You See さんからの引用

     .NET Framework 2.0 のセキュリティパッチに伴う(この場合)過剰なチェックを

     迂回する技か、なにかの設定があるのだと思っています。

    こんなものが見つかる可能性は、まずないと思います。

    2008年1月7日 11:58
  •  You See さんからの引用

    ですので、 .NET 2.0 からの呼び出し時、それもセキュリティパッチ実施にともなう非互換だと考えています。

    お話を伺う限り、何らかの非互換が生じたのは事実でしょう。

    その部分の永続的な互換をMicrosoftが保証していたかどうかは分かりません。

     

     You See さんからの引用

    例えば、LAN関係のプログラムで、ファイアウォールの例外に登録する必要があるとかの、

    そんな類の設定があるなかなと思っています。

    恐らくないでしょう。

    #あったとしても、ユーザにその脆弱になる設定を求めるのは酷です。

     

     Tom Yama さんからの引用

    # そのDLLの開発元は、何で、.Net Framework 2.0への対応を拒否しているのでしょうかね?

    # それが判れば、いくらか動きようがあるように思えますが。。

    開発元が拒否しているというより、You Seeさんの会社から要請を出したくない、あるいは出せない状況のように読み取れました。

    どういった事情でそうなのかまでは分かりませんが。

     

     

    「すぐに解決することはできない」というのが結論でしょうか。

    .NET 1.1プロセスと.NET 2.0プロセスの通信を設計・実装・テストする、DLL開発元に対応してもらう、Microsoftのサポートに期待するのいずれにしても時間がかかります。

    ユーザからのクレームで頭を悩ませることになりますが…。

    2008年1月7日 13:33
    モデレータ
  • .NET Framework 2.0 での重大な変更点

    http://www.microsoft.com/japan/msdn/netframework/programming/breakingchanges/

    すべての既知の .NET Framework 2.0 の重大な変更は詳細に検討されました。このような重大な変更には、いくつか理由があります。たとえば、標準への準拠、顧客フィードバック、および正確性などです。添付の記事で変更点のドキュメント化は徹底して行っていますが、これら変更点の多くはユーザーにはほとんど影響のないものです。ランタイム変更の例として、以下のような種類の変更があります。

     

    この文書から察するに、.NET Framework 1.1のアセンブリの.NET Framework 2.0での完全な動作は保証されていないと思います。

    初期リリースで動いていたものが動かなくなったことになりますが、「保証してません」と言われればそれまでかと…。

    2008年1月7日 13:55
    モデレータ
  • #このフォーラム、ページを切り替えないと次が見えないのですね。さっき気がつきました。

    #ページ切り替えに気がつかず、RESがついていないものと思っていました。

     

    お返事ありがとうございます。 

     

    おっしゃるように、MSのサポートに期待しても時間がかかるだろうから、何か手がないか.と期待しています。

    時間を無視した正道は、MSに (MS07-40の詳細を聞いて、もし教えてくれればですが)サポートを要求するのでしょうが・・

     

    ファイアウォールのような口は本当にないのでしょうか。

    MSも何らかの非互換は予想しているはずだから、対策も考えておくべきだと思うんだけど。

       

    DLLの対応は拒否されているわけではないのですが、作業できる人間がいない状況なのです。

    詳しくは書き込めませんが、契約がらみの制約がありまして・・

     

    使えるかどうかわかりませんが、.NET Remotingを調べています。

    これも 1.1->2.0で少し変っているみたいだけれど・・ 

       

    [ため息] 

    困ったなぁ。

    これが、1.1 -> 2.0への非互換なら、こちらも覚悟しているのですが、2.0同士での非互換なので困ります。

    少なくてもAPIレベルでは、ややこしい事はしていないはずなんだけどなぁ。

    「完全な互換はない」といわれても、「だいたいの互換」は期待するし、動作確認はちゃんとやったのに。

    2008年1月15日 1:35
  • .net2.0で問題が発生し、.net 1.1のプログラムからの呼び出しで問題が発生しないとなると、

    別プロセスの使用くらいしか逃げ道がなさそうな気がします。

    #MS-07-040はURL解析の不具合? 非互換性にはならなそうな気が・・・

     

    素人の浅知恵ですが、間に.net 1.1のActiveX実行ファイルを追加し、COMで呼び出したら

    1.1状態で実行されないでしょうか。

    こんな具合に。  メインプログラム(.net 2.0) >> [COM呼び出し] >> ActiveX(.net1.1) >> [参照] >> 問題のDLL

    2008年1月15日 11:04
  •  You See さんからの引用

    ファイアウォールのような口は本当にないのでしょうか。

    これが存在するのであれば、Microsoftのサポートからその旨、回答を得られるのではないでしょうか?

    このフォーラムでは公式の回答は得られません。社員の方からの発言もありますが、義務ではありませんので、その答えを得られる可能性は低いと思います。

     

     You See さんからの引用

    MSも何らかの非互換は予想しているはずだから、対策も考えておくべきだと思うんだけど。

    例えば次のKBでは「動作が変わるので必要であれば修正して下さい」と書いています。

     

    http://support.microsoft.com/kb/940521/ja

    (リンク元: http://support.microsoft.com/kb/931212/ja)

     

    この修正は.NET 1.1には適用されていないので、こういった類の変更が今回の問題に影響を与えていそうとは思います(他にもいくつかあります)。

    ※元のDLLがどのようにstring[]を扱っているのか存じませんので、これが該当するとは限りません。

    2008年1月15日 14:10
    モデレータ
  • 関連する話題として追記しておきます。

     

    .NET 2.0 SP1の自動更新での提供について

    http://www.microsoft.com/japan/msdn/netframework/downloads/20_30_sp1.aspx

     

    第2四半期頃に自動更新で導入されます。

    2008年1月15日 14:12
    モデレータ