簡體   English   中英

在C#中Pinvoke C ++函數傳出2個浮點數

[英]Pinvoke c++ function in c# that passes out 2 floats

我正在使用C#中的非托管c ++ dll,該dll通過USB控制measuremnet設備。 首先,我想訪問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。 但是,應包含測量值的兩個浮點值始終返回零值。

我首先創建一個包含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);
    }
}

要測試該方法,可以使用帶有按鈕和文本框的簡單表單,單擊按鈕時,將使用兩個測量值更新文本框值。

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 ++函數,但是現在有點茫然了。

該函數返回的是結構而不是浮點數。 您必須在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);

嘗試以下

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) ;

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM