4

山のような調査と実験を行った後でも、外部ライブラリから管理されていない関数にアクセスする際に発生している問題をまだ理解できません。

関連する簡単な裏話: USB 経由でシステムに接続する外部メーターを駆動するアプリケーションを Visual C++ で作成しましたが、シリアル ポートを仮想化していて、奇妙な出力動作に気付きました。製造業者は、自社の正当性を立証するために、自社の .dll を使用して、アプリケーションからメーターを制御するように求めています。いいけど....

この .dll を参照として直接含めることができませんでした (名前とパスは削除されました)。ここに画像の説明を入力

したがって、それを使用するために、おそらくDllImportに目を向けました。コードをアプリケーションに直接含めるのではなく、クラスを介して機能にアクセスできるように、ドライバーのラッパーとして独自のアセンブリを作成することにしました。.dll で dumpbin /exports を実行した後、すべての関数のエントリ ポイントを見つけ、そのような C# クラス ライブラリを作成しました。関連する例のみが含まれています。

namespace Meter
{
    public class PortDrv
    {

        [DllImport("PortDrv.dll", EntryPoint = "SERIALNUMBER",
            CallingConvention = CallingConvention.StdCall,
            CharSet = CharSet.Auto)]
        public static extern long SerialNumber(Byte Index);

        [DllImport("PortDrv.dll", EntryPoint = "OPENPORT",
            CallingConvention = CallingConvention.StdCall,
            CharSet = CharSet.Auto)]
        public static extern int OpenPort();

    };
}

関数のプロトタイプは、彼らが私に送ったライブラリの説明を記載した .pdf から抽出されました。

SERIALNUMBER (ByVal Index As Byte) As Long
OPENPORT () As Integer

また、サンプル VB プログラムでも使用されています。

Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long
Private Declare Function OpenPort Lib "PortDrv" Alias "OPENPORT" () As Integer

まだ私と一緒に?Ok。したがって、独自のアセンブリをコンパイルした後、アプリケーションへの参照を追加し、ラッパーに次のようにアクセスしました。

int port_return = PortDrv::OpenPort(); 
Byte bite = 0x31;
__int64 serial = PortDrv::SerialNumber(bite);

しかし、シリアル番号を取得しようとすると爆撃します:ここに画像の説明を入力

そして、どこが間違っているのかよくわかりません。一部の関数は正しい情報を返しますが、失敗するには情報を渡す必要があるようです。CharSets と CallingConventions のさまざまな組み合わせをすべて試してみたり、ExactSpelling を true に設定したりしました。間違っていることが明らかに明らかなことはありますか、それとも現在の環境でこのライブラリを使用できないのでしょうか?

編集:関数に「1」を渡す理由は、システムに接続されているメーターが 1 つだけの場合、「インデックス」が 1 になるためです。2 つのメーターがある場合は、 '2' を渡して 2 つ目。

4

1 に答える 1

5

あなたが与えたサンプルVBプログラム:

Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long  

とは言わないByVal。VB のデフォルトはByRef. これはあなたのタイプミスですか、それとも問題ですか? その場合はref Byte、SerialNumber への署名に記載する必要があります。

道徳:常にByRefまたはと言うByVal.

于 2012-05-04T12:28:35.103 に答える