2

KubuntuLinux上のいくつかのuser32関数のWine実装にアクセスしようとしています。Wine1.1.31パッケージをインストールしています。この簡単なテストプログラムをMonoDevelopで実行しようとすると、が表示されSystem.EntryPointNotFoundExceptionます。

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace PinvokeTesting
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(GetKeyState((int)Keys.A));
        }

        [DllImport("user32")]
        private static extern short GetKeyState(int vKey);
    }
}

これは出力です:

未処理の例外:System.EntryPointNotFoundException:GetKeyState at(ラッパー管理からネイティブ)PinvokeTesting.MainClass:GetKeyState(int)at PinvokeTesting.MainClass.Main(System.String [] args)[0x00000] in ... / Main.cs :11

関数はそこにあるはずですが、それが見つかりません。何か案は?私はたくさんの検索をしましたが、役立つものは何も見つかりませんでした。これらの問題に関するドキュメントはかなりまばらなようです(それか、間違ったものを探しています)。

編集: Winformsと組み合わせてP/Invokeを使用しようとはしていません。WineにはP/Invokeする必要のある他の機能がいくつかあります。Mono P / InvoketoWineを機能させようとしています。

4

3 に答える 3

3

Linux上のMonoでマネージドSystem.Windows.Forms実装と組み合わせてこれを実行しようとしている場合は、Wineをピンボーキングしても役に立たないと確信しています。SWFは、Wineとはまったく異なる方法で実装されており、2つは「混合」したり、相互作用したりすることはありません。

私はあなたがあなたがやろうとしていることを達成するための別の方法を見つけることを提案します。

于 2010-02-27T00:14:53.080 に答える
3

ワインライブラリはモノと完全に互換性がありません。Linuxでwinelibsを使用する必要がある場合は、Windowsバージョンのmonoを入手して、wineで実行する必要があります。

これは特にWinformsとは関係がなく、どのワインライブラリにも当てはまります。

あなたの問題の実際の解決策について:

  • 提案されている#ifdefWIN32API_NT_5トリックを使用しないでください。代わりに、ランタイム検出を使用して、Windowsまたは異なるオペレーティングシステムで実行しているかどうかに応じて、いずれかのメソッドを呼び出します。単一のバイナリを持つことは、1サイクルのランタイムの価値があります。ペナルティ(オペレーティングシステムのフラグを静的なreadnlyフィールドmonoに格納すると、チェックが最適化されます)。
  • コードを移植可能にする場合は、さまざまなオペレーティングシステムモデルに対応する必要があります。これは、あるシステムから別のシステムへのant呼び出しを、単純または完全に互換性のある方法で実装できるとは限らないためです。たとえば、GetKeyState()の場合、キーボードイベントをフックアップし、プレス/リリースの状態を自分で記録する必要がある場合があります。
  • 同じことを行うためのさまざまな方法を検討してください。たとえば、mscorlibの標準コンソールクラスがプログラムに必要な機能を提供していないことを確認しますか?
于 2010-02-27T10:20:20.057 に答える
1

あなたが発見したように、ここでの話には単純な教訓があります...使用されているピンボークがある場合は、コードがクロスプラットフォームのポータブルでワイン互換であると想定しないでください!これを回避できる唯一のことは、次のようなものです。

システムを使用する;
System.Runtime.InteropServicesを使用します。
System.Windows.Formsを使用します。

名前空間PinvokeTesting
{{
    クラスMainClass
    {{
        public static void Main(string [] args)
        {{
            Console.WriteLine(GetKeyState((int)Keys.A));
        }

#ifdef WIN32API_NT_5
        [DllImport( "user32")]
        private static extern short GetKeyState(int vKey);
#そうしないと
        private static extern short GetKeyState(int vKey);
#endif
    }
}

そして、Win32APIpinvoke署名の代わりに何らかのラッパーを作成します。参照しているからといっSystem.Windows.Formsて、WIN32APIピンボークがWineで機能することを意味するわけではありません。これは、GUIに関するさまざまな基盤となるインターフェイスが異なり、移植性が保証されていないためです。

次に、スイッチ'WIN32API_NT_5'を定義するか、このクロスプラットフォームを使いやすくしたい場合は、独自に選択したいものを定義します。

これがお役に立てば幸いです、よろしく、トム。

于 2010-02-27T00:22:22.937 に答える