C# 从C++;(非托管代码)到C Sharp表单(托管) 我在C++中实现了以下(已经创建了一个DLL)

C# 从C++;(非托管代码)到C Sharp表单(托管) 我在C++中实现了以下(已经创建了一个DLL),c#,c++,dllimport,dllexport,unmanaged-memory,C#,C++,Dllimport,Dllexport,Unmanaged Memory,在头文件中 我试着用C-sharp接收这个 [DllImport("C:\\Users\\BME 320 - Section 1\\Documents\\Visual Studio 2015\\Projects\\EyeTrackDll\\x64\\Debug\\EyeTrackDll.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr eyeData(); 但我不知道如何接收butto

在头文件中

我试着用C-sharp接收这个

[DllImport("C:\\Users\\BME 320 - Section 1\\Documents\\Visual Studio 2015\\Projects\\EyeTrackDll\\x64\\Debug\\EyeTrackDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr eyeData();
但我不知道如何接收buttonClick事件中的数组


非常感谢您在这方面的帮助。

按照@DavidHeffernan的提示,我将尝试为您提供一个如何实现目标的示例。请把C#部分当作伪代码,因为我不是那种语言的专家

我将使用前面所说的结构,只是为了使事情更清楚,我认为给出一些类型保护是一个好的做法,如果不知道有多少个双倍的话,有可能向结构添加一个“大小”属性。在您的情况下,像往常一样,不需要4

函数:

void getData(double* eyeTrackData)
{
    const unique_ptr<Fove::IFVRHeadset> headset{ Fove::GetFVRHeadset() };

    CheckError(headset->Initialise(Fove::EFVR_ClientCapabilities::Gaze), "Initialise");

    Fove::SFVR_GazeVector leftGaze, rightGaze;
    const Fove::EFVR_ErrorCode error = headset->GetGazeVectors(&leftGaze, &rightGaze);


    // Check for error
    switch (error)
    {

    case Fove::EFVR_ErrorCode::None:
        eyeTrackData[0] = (double)leftGaze.vector.x;
        eyeTrackData[1] = (double)leftGaze.vector.y;
        eyeTrackData[2] = (double)rightGaze.vector.x;
        eyeTrackData[3] = (double)rightGaze.vector.y;
        break;

    default:
        // Less common errors are simply logged with their numeric value
        cerr << "Error #" << EnumToUnderlyingValue(error) << endl;
        break;
    }
}

再次为我的“坏C#”xD道歉。希望这有帮助。

getData()是否保持不变?在c#end接收它们怎么样?LuisGP解决方案可以工作,但它会产生内存泄漏,因为getDat()返回一个通过new分配的double数组,而.Net不知道如何释放它。将该方法更改为使用调用方提供的双缓冲区,或者继续使用IntPtr return,提供一个附加的deleteData()-方法来释放IntPtr,并使用System.Runtime.Interop.Marshal.PTRTOStructure当然,您必须使用结构而不是双*。在C方面,我不是专家。正如wech所说,如果你不提供deleteData()方法来管理内存的释放,它将产生内存泄漏。根本不需要使用结构。胡说IntPtr很好。您可以使用封送处理类来读取非托管内存。Deallocator必须导出到。或者在共享堆上分配。这就是我被卡在C-sharp端的地方:私有void按钮1_-Click(对象发送者,事件参数e){IntPtr ipr=eyeData();double[]eyeTrackData=new double[10];int j=0;eyeTrackData[0]=Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(ipr,11*j));最后一行给出了错误。另外,我正在传递双精度类型的数组,那么我该如何处理?使用Marshal.Copy读取数组。但是,您计划如何取消分配数组?调用者如何知道数组的长度?如果长度是固定的,则调用者最好进行分配。
[DllImport("C:\\Users\\BME 320 - Section 1\\Documents\\Visual Studio 2015\\Projects\\EyeTrackDll\\x64\\Debug\\EyeTrackDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr eyeData();
void getData(double* eyeTrackData)
{
    const unique_ptr<Fove::IFVRHeadset> headset{ Fove::GetFVRHeadset() };

    CheckError(headset->Initialise(Fove::EFVR_ClientCapabilities::Gaze), "Initialise");

    Fove::SFVR_GazeVector leftGaze, rightGaze;
    const Fove::EFVR_ErrorCode error = headset->GetGazeVectors(&leftGaze, &rightGaze);


    // Check for error
    switch (error)
    {

    case Fove::EFVR_ErrorCode::None:
        eyeTrackData[0] = (double)leftGaze.vector.x;
        eyeTrackData[1] = (double)leftGaze.vector.y;
        eyeTrackData[2] = (double)rightGaze.vector.x;
        eyeTrackData[3] = (double)rightGaze.vector.y;
        break;

    default:
        // Less common errors are simply logged with their numeric value
        cerr << "Error #" << EnumToUnderlyingValue(error) << endl;
        break;
    }
}
[DllImport("C:\\Users\\BME 320 - Section 1\\Documents\\Visual Studio 2015\\Projects\\EyeTrackDll\\x64\\Debug\\EyeTrackDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void eyeData(IntPtr); 

private void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
        IntPtr ipr = Marshal.AllocHGlobal(4); // Memory blob to pass to the DLL
        eyeData(ipr);
        double[] eyeTrackData = new double[4]; // Your C# data
        Marshal.Copy(ipr, eyeTrackData, 0, 4); // Convert?
    }
    finally 
    { 
        Marshal.FreeHGlobal(ipr); 
    }
}