Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
封送浮点*到C#_C#_C++_Memory Management_Dll_Marshalling - Fatal编程技术网

封送浮点*到C#

封送浮点*到C#,c#,c++,memory-management,dll,marshalling,C#,C++,Memory Management,Dll,Marshalling,我有一个DLL,它导出一个返回浮点*的函数,我想在我的C#代码中使用它。我不知道如何封送我的浮点*以便在C#中安全地使用它。 因此,在我的C++ DLL中,我声明: static float* GetSamples(int identifier, int dataSize); 在我的C#脚本中,我有: [DllImport ("__Internal")] public static extern float[] GetSamples (int identifier, int dataSize)

我有一个DLL,它导出一个返回浮点*的函数,我想在我的C#代码中使用它。我不知道如何封送我的浮点*以便在C#中安全地使用它。 因此,在我的C++ DLL中,我声明:

static float* GetSamples(int identifier, int dataSize);
在我的C#脚本中,我有:

[DllImport ("__Internal")]
public static extern float[] GetSamples (int identifier, int dataSize);

C++的GETSAMPLE(int,int)分配内存并返回指针数组浮点数组。如何声明C#GetSamples来封送浮点数组,如何访问数据(通过迭代或Marshal.Copy)? 另外,我能从C中删除浮点*还是必须调用另一个C++函数来删除分配的内存?< /P> 编辑: 这就是我到目前为止一直在尝试的。 首先,在C方面:

声明:

[DllImport ("__Internal")]
public static extern int GetSamples ([In, Out]IntPtr buffer,int length, [Out] out IntPtr written);
试着称之为:

IntPtr dataPointer = new IntPtr();
IntPtr outPtr;
GetSamples(dataPointer, data.Length, out outPtr);
for (var i = 0; i < data.Length; i++){
    copiedData[i] = Marshal.ReadByte(dataPointer, i);
}

我真的不知道outPtr是做什么用的。。。我知道我还有一些额外的复制步骤可以删除,我现在只想让它工作。

所以这是一个有点复杂的答案

NET不知道如何处理C++内存分配,因此,不管返回<代码>浮点*>代码>,这是最危险的。此外,.NET内存模型是基于COM的,因此它是基于
CoTaskMemAlloc
的,并不是说它在这方面对您有帮助。下面是我的建议:

传递bufferLength为零将返回缓冲区所需的空间,然后可以分配并传入该空间


您需要在C#中为缓冲区分配内存,而在C++中无法分配内存,因此这是一个有点复杂的答案

NET不知道如何处理C++内存分配,因此,不管返回<代码>浮点*>代码>,这是最危险的。此外,.NET内存模型是基于COM的,因此它是基于
CoTaskMemAlloc
的,并不是说它在这方面对您有帮助。下面是我的建议:

传递bufferLength为零将返回缓冲区所需的空间,然后可以分配并传入该空间


您需要在C#中为缓冲区分配内存,但无法在C++中分配它。

您控制该DLL的代码吗?是的,我控制该DLL的代码。您控制该DLL的代码吗?是的,我控制该DLL的代码。编写的代码是什么?我尝试过实现这个,但仍然有问题。我声明一个ItpTR,我作为SAMPLE缓冲区,并使用C++中的MimcPy来分配一些数据给它--> MeMCPY(sampleBuffer,MyDATA,BuffelSt*sisiof(浮点));然后在C端,我尝试使用Marshal.ReadByte(dataPointer,I)读取它;,但是我遇到了一个严重的访问错误。我是个新手,有什么建议吗?我将用更多细节更新我的问题。IntPtr包含对要分配的C#数组的引用,它本身只是一个指针持有者。你会调用pINKEK两次,一次得到数组的大小分配(如果你永远不会分配这么多内存,写的是int而不是int),但是如果你用C语言写的改变它也改变C++中的int值,那么分配的大小将以书面形式返回。第二个调用将使用分配给缓冲区intptr的数组,即分配给长度的长度intptr@DavidMenard我已经编辑了我的示例以便更易于使用,但是有一个提醒,您确实需要用C而不是C++进行内存分配,因此我仍然无法调用该方法。问题是我在Unity3d中,不能使用“不安全”,所以不能使用IntPtr.ToPointer()。宣布新的浮动[dataLen];在C边,把它作为浮点*传递给C++也不起作用。在C#中永远不需要使用
不安全的
。书面语言做什么?我尝试过实现这个,但仍然有问题。我声明一个ItpTR,我作为SAMPLE缓冲区,并使用C++中的MimcPy来分配一些数据给它--> MeMCPY(sampleBuffer,MyDATA,BuffelSt*sisiof(浮点));然后在C端,我尝试使用Marshal.ReadByte(dataPointer,I)读取它;,但是我遇到了一个严重的访问错误。我是个新手,有什么建议吗?我将用更多细节更新我的问题。IntPtr包含对要分配的C#数组的引用,它本身只是一个指针持有者。你会调用pINKEK两次,一次得到数组的大小分配(如果你永远不会分配这么多内存,写的是int而不是int),但是如果你用C语言写的改变它也改变C++中的int值,那么分配的大小将以书面形式返回。第二个调用将使用分配给缓冲区intptr的数组,即分配给长度的长度intptr@DavidMenard我已经编辑了我的示例以便更易于使用,但是有一个提醒,您确实需要用C而不是C++进行内存分配,因此我仍然无法调用该方法。问题是我在Unity3d中,不能使用“不安全”,所以不能使用IntPtr.ToPointer()。宣布新的浮动[dataLen];在C边,把它作为浮点*传递给C++也不起作用。在C#中不应该使用
不安全的
int AudioReader::RetrieveSamples(float * sampleBuffer, size_t dataLength, size_t * /* out */ written)
{
    float* mydata = new float[dataLength];

    //This is where I copy the actual data into mydata

    memcpy(sampleBuffer, mydata, dataLength*sizeof(float));

    delete data;
    return dataLength;
}
int AudioReader::RetrieveSamples(
     float * sampleBuffer,
     int dataLength,
     int * /* out */ written)
{
     // assuming mydata is already defined
     if(sampleBuffer == NULL || dataLength == 0)
     {
         *written = sizeof(mydata);
         return -1;
     }
     ZeroMemory(sampleBuffer, dataLength);
     int toCopy = min(dataLength, sizeof(myData));
     //This is where I copy the actual data into mydata

     memcpy(sampleBuffer, mydata, toCopy);
     *written = toCopy;
     return 0;
 }
 [DLLImport("__internal")]
 private static extern int GetSamples(
     [In, Out]IntPtr buffer,
     [In] int length,
     [Out] out int written);

 float[] RetrieveFloats()
 {
     int bytesToAllocate = 0;
     GetSamples(IntPtr.Zero, 0, out bytesToAllocate);
     if(bytesToAllocate == 0)
        return null;
     int floatCount = bytesToAllocate/ sizeof(float);
     float[] toReturn = new float[floatCount];
     IntPtr allocatedMemory = Marshal.AllocHGlobal(bytesToAllocate);

     int written = 0;
     if(GetSamples(allocatedMemory, bytesToAllocate, out written) != -1)
     {
         floatCount = written/sizeof(float);
         Marshal.Copy(allocatedMemory, toReturn, 0, floatCount);
     }
     Marshal.FreeHGlobal(allocatedMemory);
     return toReturn;
 }