2

USB経由でmeasuremnetデバイスを制御するC#のアンマネージドc++dllを使用しています。開始するには、デバイスから測定値を返し、次のようなドキュメントで定義されているdll内の関数にアクセスしたいと思います。

BOOL WINAPI LKIF_GetCalcData(OUT LKIF_FLOATVALUE *CalcData1,OUT LKIF_FLOATVALUE *CalcData2);

typedef enum {
    LKIF_FLOATRESULT_VALID, // valid data
    LKIF_FLOATRESULT_RANGEOVER_N, // over range at negative (-) side
    LKIF_FLOATRESULT_WAITING, // comparator result
} LKIF_FLOATRESULT;

typedef struct {
LKIF_FLOATRESULT FloatResult; // valid or invalid data.
    float Value; // measurement value during LKIF_FLOATRESULT_VALID. 
    Any other times will return an invalid value.
} LKIF_FLOATVALUE;

dllを使用するのはこれが初めてなので、PInvokeを使用してC#で関数を定義する方法を検索するのにかなりの時間を費やし、部分的に機能させることができました。関数を呼び出すことができますが、関数の実行時にtrueまたはfalseの値が正しく返されるように見えます。たとえば、デバイスがオンで準備ができている場合はtrueを返し、デバイスをオフにするとfalseを返します。ただし、測定値を含む必要がある2つのfloat値は、常にゼロの値を返します。

PInvokeを含むクラスを作成することから始めました。

public class Keyence
{
    [DllImport("c:\\LkIF.dll")]
    public static extern bool LKIF_GetCalcData(
        [Out] float CalcData1, [Out] float CalcData2);
}

次に、これはgetMeasurementメソッドによって呼び出されます。

static bool getMeasurement(ref float MeasurementValue1, ref float MeasurementValue2)
{
    float CalcData1 = new float();
    float CalcData2 = new float();

    bool sucess = Keyence.LKIF_GetCalcData(CalcData1,CalcData2);

    if (sucess)
    {
        // all is ok
        MeasurementValue1 = CalcData1;
        MeasurementValue2 = CalcData2;
        return (sucess);
    }
    else
    {
        MessageBox.Show("Unable to get measurment.");
        return (sucess);
    }
}

メソッドをテストするには、ボタンとテキストボックスを備えた単純なフォームを使用し、ボタンをクリックすると、テキストボックスの値が2つの測定値で更新されます。

private void button1_Click(object sender, EventArgs e)
{
    float MeasurementValue1 = new float();
    float MeasurementValue2 = new float();
    bool success = getMeasurement(ref MeasurementValue1, ref MeasurementValue2);
    if (success)
    {
        textBox1.Text = MeasurementValue1.ToString() + "," + MeasurementValue2.ToString();
    }      
}

ボタンをクリックすると、テキストボックスの値が0,0に更新されます。

値が渡されるアンマネージ関数の呼び出しを伴うスレッドをたくさん見てきましたが、関数が値を返すことはそれほど多くありませんでした。C#でC ++関数を正しく定義していないように感じますが、今は少し途方に暮れています。

4

2 に答える 2

4

この関数は、floatではなく構造体を返します。その構造体をC#コードで宣言する必要があります。

public enum LKIF_FLOATRESULT
{
    LKIF_FLOATRESULT_VALID, 
    LKIF_FLOATRESULT_RANGEOVER_N, 
    LKIF_FLOATRESULT_WAITING
}

[StructLayout(LayoutKind.Sequential)]
public struct LKIF_FLOATVALUE
{
    public LKIF_FLOATRESULT FloatResult; 
    public float Value; 
}

次に、p / invokeを定義して、その構造体をoutパラメーターとして関数に渡します。

[DllImport(@"c:\LkIF.dll")]
public static extern bool LKIF_GetCalcData(
    out LKIF_FLOATVALUE CalcData1, 
    out LKIF_FLOATVALUE CalcData2
);

そして最後に、次のような関数を呼び出します。

LKIF_FLOATVALUE CalcData1;
LKIF_FLOATVALUE CalcData2;
bool success = Keyence.LKIF_GetCalcData(out CalcData1, out CalcData2);
于 2012-05-23T21:31:21.087 に答える
0

次を試してください

public enum LKIF_FLOATRESULT {
    LKIF_FLOATRESULT_VALID,
    LKIF_FLOATRESULT_RANGEOVER_N,
    LKIF_FLOATRESULT_WAITING,
}

public struct LKIF_FLOATVALUE {
    public LKIF_FLOATRESULT FloatResult;
    public float Value;
}

public partial class NativeMethods {

    [DllImport("c:\\LkIF.dll")]
    public static extern  bool LKIF_GetCalcData(
        out LKIF_FLOATVALUE CalcData1, 
        out LKIF_FLOATVALUE CalcData2) ;

}
于 2012-05-23T21:29:47.317 に答える