[英]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.