2012-05-03 11 views
4

調査と実験の後、私はまだ外部ライブラリから管理されていない関数にアクセスしている問題を理解できません。.dllをインポートするためのC#ラッパー "保護されたメモリを読み書きしようとしました"

私は、USB経由でシステムに接続しているシリアルポートを仮想化する外部メーターを駆動するためにVisual C++でアプリケーションを作成しましたが、私は奇妙な出力動作に気づいていました。自信を持つために、製造元は自分のアプリケーションからメーターを制御するために.dllを使用することを望んでいます。 enter image description here

だから、それを使用するためには、私はおそらくDLLIMPORTに見えた:ファイン、しかし....

は私が.DLL直接参照(取り外し名&パス)としてこれを含めることができませんでした。私のアプリケーションに直接コードを組み込むのではなく、自分のアセンブリをドライバのラッパーとして作ってクラスを通して機能にアクセスできるようにしました。 .dllファイルのDUMPBIN /輸出を行った後、私はすべての関数のエントリポイントを発見し、そのような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(); 

    }; 
} 

を関数のプロトタイプは以下から引き出されましたそのサンプルのVBプログラムでも

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

とを使用している:私と一緒にまだ

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

彼らは私が彼らのライブラリを記述送っ.PDF? OK。だから、私自身のアセンブリをコンパイルした後、私は自分のアプリケーションへの参照を追加し、のようなラッパーにアクセス:

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

しかし、爆弾のシリアルナンバー取得しようとした後:enter image description here

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

EDIT:システムに接続されているメーターが1つだけの場合、「1」を渡す理由は忘れていましたが、「インデックス」は1になります。私は '2'を渡すことで2番目のものにアクセスすることができました。

+0

よろしくお願いいたします。メーカーが.NETラッパーを提供したり、.NET環境用のサンプルコードを提供したりすることはできません。明らかな困難があれば、これは不合理な要求のようには見えません。 –

+0

Hmm。 0x31は有効な入力ですか? – Cameron

+0

@Cameron:私はそう信じています。私も '1'&1で渡してみました。私は、文字を明示的に述べることによってすべての誤った解釈を除外したかったのです。または、0x01を渡す必要があることを暗示していますか。 –

答えて

5

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

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

ByValを言うことはありません。 VBのデフォルトはByRefです。これはあなたの部分のタイプミスですか、それとも問題ですか?その場合は、SerialNumberの署名にref Byteと言う必要があります。

モラル:常にByRefまたはByValと言ってください。

+0

上記の行は、ドライバを使用するサンプルプログラムに含まれています。それはあなたが私のコードだと思っていたかもしれないようですが、そうではありません、私はそれをまっすぐに引いて正しいものにしました。彼らのプロトタイプでは、バイトはByVal: 'SERIALNUMBER(ByValインデックスBy Byte)As Long'を渡されます。それは彼らの面倒な問題ですか? –

+0

シグネチャをref Byteに変更しましたが、メモリの障害が解消しましたが、関数は何も返しません(intとlongを使用)。それはトピックの焦点だったので、私はあなたの答えを正しいものにしたいと思っていますが、私の問題はまだ消えていないので、私はそれを今のところ開いておきたいと思います。 –

+0

これは基本的に一致するはずです。だから1人は間違っているはずです。 – Ben

関連する問題