English 中文(简体)
Pinvoke c+++ 函数在 c# 中传递两个浮点
原标题:Pinvoke c++ function in c# that passes out 2 floats
  • 时间:2012-05-23 21:23:55
  •  标签:
  • c#
  • c
  • pinvoke

我正在与 C# 中一个未管理的 c++ dll 工作, 控制在 USB 上的测量网设备。 首先, 我希望能在 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;

由于这是我第一次用一个模版工作,我花了相当长的时间来寻找如何使用 PInvoke 来定义 C# 中的函数, 我设法使它部分发挥作用。 我能够调用该函数, 当函数执行时它似乎返回了一个真实或错误的值。 例如, 如果设备打开并准备好, 它返回了真实的值, 如果我关闭了设备, 它返回了虚假的值。 但是, 包含测量值的两个浮点值总是返回零值 。

我首先创建了一个包含Pinvoke的班级:

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

以测量方法称它为:

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 来将这一支架传递到函数, 作为输出参数 。

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

}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签